Estou tentando inserir texto variável após outro texto variável em uma linha específica. Abaixo está minha tentativa até agora, até onde eu sei, se eu conseguir escapar das aspas awk
para que a variável possa ser vista e ainda aplicada, então deve funcionar, mas não tenho ideia de como fazer isso:
#!/bin/sh
VAR=$(head -n1 ~/Scripts/tmp/file.txt)
VAR1=$(head -n1 ~/Scripts/tmp/file1.txt)
awk '/$VAR/ { print; print "$VAR1"; next }1' ~/Scripts/tmp/file.txt
Responder1
Para passar strings para um script awk, passe-as por meio de variáveis de ambiente.
export VAR VAR1
awk '
1
$0 == ENVIRON["VAR"] {print ENVIRON["VAR1"]}
' ~/Scripts/tmp/file.txt
Reorganizei seu script para tornar a lógica mais simples. Também substituí a correspondência de regexp por uma comparação de strings: com a correspondência de regexp, $VAR
seria tratada como uma expressão regular, não realizaria uma comparação de strings. E /$VAR/
nem usaria o valor de VAR
(essa é a sintaxe Perl, não awk), que você precisaria match($0, VAR)
para isso.
Uma nota sobre algumas outras soluções que realmente não funcionam (elas funcionam apenas se as variáveis não contiverem nenhum caractere especial, qual caractere é especial depende do método):
awk -v awkvar="$VAR" '$0 == awkvar …'
expande barras invertidas no conteúdo da linha.awk "/$VAR/" …
faz com que o shell expanda o valor deVAR
um trecho do awk. Por exemplo, sefile.txt
contém^/ {system("touch ~/naughty")} /
, o comandotouch ~/naughty
é executado.
Uma abordagem alternativa é fazer com que o awk leia todos os arquivos.
awk '
BEGIN { VAR1 = getline <"~/Scripts/tmp/file1.txt"; }
NR == 1 {VAR = $0}
1
$0 == ENVIRON["VAR"] {print ENVIRON["VAR1"]}
' ~/Scripts/tmp/file.txt
Responder2
Uma possível solução AWK:
awk '/'$VAR'/ { print; print "'$VAR1'"; next }1'
quebre as 'aspas em torno de todas as suas variáveis externas.
Outra solução possível, como a outra postagem sugerida com a passagem de variáveis, é passar VAR1 como uma variável awk, mas acho que você ainda precisa fazer o escape do bloco de aspas simples para o padrão usando VAR:
awk -v var=$VAR1 '/'$VAR'/ { print; print var; next }1'
Você poderia tentar o sed :) ele foi projetado especificamente para esse tipo de substituição.
sed "s/$VAR.*/\0\n$VAR1/" ~/Scripts/tmp/file.txt
se você puder ter várias instâncias de VAR em uma única linha, adicione g no final do comando sed (global) para que ele não pare na primeira correspondência que encontrar:
sed "s/$VAR.*/\0 $VAR1/g" ~/Scripts/tmp/file.txt
IMPORTANTE!: certifique-se de que o caracter '/' não apareça na variável VAR ou VAR1, se puder, você precisará escapá-los para awk ou sed, alternativamente com sed você pode alterar o delimitador do comando para algo como '; ' por exemplo:
sed "s;$VAR.*;\0\n$VAR1;" ~/Scripts/tmp/file.txt
Explicação do comando sed:
Usamos aspas duplas" em vez de aspas simples ao redor do comando sed para que variáveis como VAR e VAR1 sejam substituídas por seus valores. Isso acontece antes do comando ser executado por sed, por isso se o / pode esteja presente no conteúdo da variável que você precisa para endereçá-lo (isso também é válido para o awk).
O 's' indica que você está escrevendo um comando de substituição no formato:
s/<padrão>/<padrão de substituição>/
O '/ ' imediatamente após o s é o delimitador que será usado para separar as seções do comando, então se você colocar ; você deve usar em todos os lugares como mostrado acima. o padrão é \0, o que significa imprimir o que foi correspondido pelo padrão, uma nova linha '\n' e o conteúdo de VAR2.
OOPS não viu a parte sobre a linha abaixo.. padrões fixos.
Responder3
Se quiser usar awk
, tem que passar a bash
variável para awk
com a -v
opção:
awk -v v=$VAR -v v1=$VAR1 '/v/ { print; print v1; next }1' ~/Scripts/tmp/file.txt
Mas verifique a resposta de Rob para uma solução mais correta e detalhada.