insere texto variável depois de outro texto variável em uma linha específica

0

Estou tentando inserir texto variável após outro texto variável em uma linha específica. Abaixo está a minha tentativa até agora, tanto quanto eu posso dizer, se eu posso escapar as cotações em awk para que a variável possa ser vista e ainda aplicada, então deve funcionar, mas não tenho idéia 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
    
por Giles 18.05.2016 / 14:51

3 respostas

2

Para passar strings para um script awk, passe-as por variáveis de ambiente.

export VAR VAR1
awk '
    1
    $0 == ENVIRON["VAR"] {print ENVIRON["VAR1"]}
' ~/Scripts/tmp/file.txt

Eu reorganizei seu script para simplificar a lógica. Eu também substituí a correspondência de expressão regular por uma comparação de string: com a correspondência de expressão regular, $VAR seria tratado como uma expressão regular, não executaria uma comparação de cadeia de caracteres. E /$VAR/ nem usaria o valor de VAR (que é sintaxe Perl, não awk), você precisaria de 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 as barras invertidas no conteúdo da linha.
  • awk "/$VAR/" … faz o shell expandir o valor de VAR como um fragmento do awk. Por exemplo, se file.txt contiver ^/ {system("touch ~/naughty")} / , o comando touch ~/naughty será executado.

Uma abordagem alternativa é fazer o awk ler 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
    
por 19.05.2016 / 02:02
1

Uma solução possível de AWK:

   awk '/'$VAR'/ { print; print "'$VAR1'"; next }1'

quebre as "citações em torno de toda a sua variável externa.

Outra solução possível, como o outro post sugere ao passar variáveis, é passar VAR1 como uma variável awk, mas eu 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 sed em vez disso :) é especificamente projetado para esse tipo de substituição.

 sed "s/$VAR.*/
 sed "s/$VAR.*/
 sed "s;$VAR.*;
   awk '/'$VAR'/ { print; print "'$VAR1'"; next }1'
\n$VAR1;" ~/Scripts/tmp/file.txt
$VAR1/g" ~/Scripts/tmp/file.txt
\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:

 awk -v var=$VAR1 '/'$VAR'/ { print; print var; next }1'

IMPORTANTE !: certifique-se de que o caractere '/' não apareça na variável VAR ou VAR1, se você precisar deles para awk ou sed, como alternativa, com sed você pode alterar o delimitador do comando para outra coisa gostar ';' por exemplo:

 sed "s/$VAR.*/
 sed "s/$VAR.*/
 sed "s;$VAR.*;%pre%\n$VAR1;" ~/Scripts/tmp/file.txt
$VAR1/g" ~/Scripts/tmp/file.txt
\n$VAR1/" ~/Scripts/tmp/file.txt

Explicação do comando sed:
        Usamos as 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, e é por isso que o / pode estar presente na variável que você precisa para resolver isso (isso é verdade para o awk também)
        O 's' indica que você está escrevendo um comando de substituição do formulário:
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 a ser correspondido será o conteúdo da variável $ VAR.         O padrão de substituição é \ 0 que significa imprimir o que corresponde ao 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.

    
por 18.05.2016 / 15:08
-1

Se você quiser usar awk , precisará passar a variável bash para awk com a opção -v :

awk -v v=$VAR -v v1=$VAR1 '/v/ { print; print v1; next }1' ~/Scripts/tmp/file.txt

Mas confira a resposta de Rob para obter uma solução mais correta e detalhada.

    
por 18.05.2016 / 15:12

Tags