Eu tenho dados de teste em um arquivotext.txt
a
b
test
test2
1,2
3,3
Eu quero gerar o arquivo a partir do número da linha em que test é + 2. Eu preciso que isso seja um oneliner utilizável em gnuplot
, cheguei ao seguinte:
awk -v linestart=$(awk '$0~"test" {a=NR}END{print a+2}' $filename) 'BEGIN{FS=",";OFS="\t";lines}NR>=linestart{print $1, $2}' $filename
mas eu preciso de alguma forma fornecer o conteúdo do arquivo para dois awk
que não sei como fazer. Então eu vim com a solução com o $filename
mas isso tem o problema, como entrar $filename
.
Eu estava pensando na linha:
echo "test.txt" | read filename | awk -v linestart=$(awk '$0~"test" {a=NR}END{print a+2}' $filename) 'BEGIN{FS=",";OFS="\t";lines}NR>=linestart{print $1, $2}' $filename
mas isso não funciona.
De que outra forma posso fazer o trabalho acima? O problema óbvio é que eu preciso saber o número da linha onde quero começar a imprimir antes de executar awk
. eu também estava pensando em algo sobre isso:
awk 'BEGIN{FS=",";OFS="\t";lines=100000}{if ($0~"test"){lines=NR+2}; if(NR>=lines){print $1, $2}}'
Mas eu nem tentei pois, é muito feio e não geral, tenho que fazer a variável lines
sempre suficientemente grande. Então, existe uma solução elegante que funcionaria com um pipe de arquivo de texto normal ou, no outro caso, com alguma maneira de inserir o nome do arquivo?
Usando
ed
:No
ed
editor, o comando/^test/+2,$p
imprimiria (p
) as linhas de duas linhas além da linha correspondente^test
, até o final ($
).Usando
awk
:Aqui, uma linha será impressa se
flag
for 1 e secount
for menor ou igual a zero. O sinalizador é definido como 1 quando o padrão^test
é correspondido nos dados de entrada ecount
também é definido para o número de linhas a serem ignoradas até que a saída deva iniciar (sem contar a linha atual). Ocount
é diminuído para todas as linhas.Uma abordagem um pouco diferente com
awk
:Aqui, combinamos nosso padrão e imediatamente lemos e descartamos a próxima linha de entrada. Em seguida, usamos um loop while para ler o restante do arquivo, imprimindo cada linha lida.
Exatamente a mesma abordagem, mas com
sed
:Combine o padrão, então leia e descarte a próxima linha (
n
), então entre em um loop lendo e imprimindo cada linha (n; p;
). O loop é composto pelo rótuloagain
e a ramificação/salto para este rótulo (b again
).Se você sabe que seus dados começam 2 linhas depois
test
de , e não há mais linhastest
neles, você pode se safar com algo assim:Além disso, para enviar esses dados para o Gnuplot, você pode considerar fazê-lo através de um pipe como este:
Você pode fazer isso trivialmente com um
start, end
intervalo com uma condição final que é sempre falsa e uma condição inicial que pula linhas:Veja também https://stackoverflow.com/a/17914105/1745001