Você tem que passar a variável shell $ j para awk:
awk -v jj="$j" '...'
Observe que isso pressupõe que o valor da variável não contenha barras invertidas, pois o argumento para awk -v é submetido à expansão de barra invertida.
Eu estou tentando pegar 100 linhas após o texto "time: X" com X em {0,40,80, ..., 200}. Aqui está o que eu tenho até agora:
#!/bin/bash
start=1
end=5
for i in $(seq $start $end);do
j=$(($i*40))
awk '/time: $j/{for(i=1;i<=100;i++}{getline;print}}' file > fileX-$j.txt
done
No entanto, isso não parece funcionar. Minha pergunta especificamente é sobre a variável $ j e como eu preciso defini-la logo após '/ time: ...'
Por exemplo, eu tenho um arquivo chamado 'file':
time: 1
1 2 3
1 33 1
2 31 4
time: 40
2 1 3
9 8 77
1 3 4
Eu gostaria de criar dois arquivos separados nesse caso; primeiro contendo
1 2 3
1 33 1
2 31 4
e o segundo com:
1 2 3
1 33 1
2 31 4
Eu tentei passar $ j como uma variável como mazs mencionou, mas ainda me dá arquivos vazios. Aqui está como eu fiz:
awk -v jj=$j '/time: jj/{for(i=1;i<3;i++){getline;print}}' file > fileX-$j.txt
Você tem que passar a variável shell $ j para awk:
awk -v jj="$j" '...'
Observe que isso pressupõe que o valor da variável não contenha barras invertidas, pois o argumento para awk -v é submetido à expansão de barra invertida.
Existem dois problemas. A primeira é que o shell não expande $j dentro de aspas simples: '$j' informa ao shell que você deseja a string $j , não o valor da variável j .
Nesse caso, como o valor contém apenas dígitos, você pode colocá-lo fora das aspas simples:
awk '/time: '"$j"'/{for(i=1;i<=100;i++}{getline;print}}' file > fileX-"$j".txt
Observe que, se o valor de j continha caracteres especiais regexp ( . , * , etc.), esses caracteres seriam interpretados como tal. Por exemplo
j='2*3'
awk '/foo '"$j"' bar/'
o script imprime linhas contendo itens como foo 3 bar , foo 23 bar , foo 223 bar , etc. e não foo 2*3 bar . E se houvesse um / no valor, o awk veria o final da construção de correspondência de expressão regular; por exemplo
j='2/3'
awk '/foo '"$j"' bar/'
resultaria em awk reclamando que a sequência de tokens /foo 2/ , 3 , bar , / não está sintaticamente correta.
Você pode definir uma variável para um awk com a opção de linha de comando -v :
j='a\tb'
awk -v j="$j" '{print j}'
Observe que isso realiza uma expansão de barra invertida no valor de j . Por exemplo, o snippet acima substitui cada linha por a↦b , em que ↦ é um caractere de tabulação.
Mas isso não funciona diretamente no seu caso, porque o awk não expande variáveis dentro de /…/ : /foo/ corresponde à string foo , não o valor da variável foo . Para usar uma variável em uma correspondência de expressão regular, você precisaria usar a função match :
awk -v j="$j" 'match($0, "time: "+j) {for(i=1;i<=100;i++}{getline;print}}' file > fileX-"$j".txt
Este funciona para valores de j que não contêm uma barra invertida; uma barra está ok. Por exemplo, com j definido como a/b*c , isso corresponderia a linhas como time: a/c , time: a/bc , etc. Com j definido como \t , isso corresponderia às linhas contendo time: seguido por um espaço e uma aba.
Para passar o valor de uma variável do shell para o awk, não importa qual seja o valor, passe-o pelo ambiente.
export j
awk 'match($0, "time: "+j) {for(i=1;i<=100;i++}{getline;print}}' file > fileX-"$j".txt
ou, para evitar que j permaneça no ambiente pelo resto do script:
j="$j" awk 'match($0, "time: "+j) {for(i=1;i<=100;i++}{getline;print}}' file > fileX-"$j".txt
E se você quisesse pesquisar uma string literal, em vez de uma expressão regular, poderia usar a função index em vez de match . Por exemplo
j='a*b'
awk 'index($0, "time: "+j)'
imprime linhas contendo time: a*b .