Erro sed que substitui a string parcial pela variável [duplicata]

1

Eu tenho 3 arquivos de texto. Quero pesquisar file3 para uma string em file2 e substituí-la por uma string em file1 em encontrado. Preciso anexar uma tag personalizada de file1 ao final da string em file3 , substituindo a string parcial encontrada em file2 .

file3

aws ec2 create-tags --region us-east-1 --resourcesi-XXXXX --tags Key=Developer Name,Value=XXXXX Key=Resource Group,Value=arn:aws:iam::XXXXX:root
aws ec2 create-tags --region us-east-1 --resourcesi-XXXX --tags Key=Developer Name,Value=XXXXX Key=Resource Group,Value=arn:aws:iam::XXXXX:user/user

file2

arn:aws:iam::XXXXX:root 
arn:aws:iam::XXXXX:user/user

file1

my_custom_tag_1
my_custom_tag_2

Saída desejada:

aws ec2 create-tags --region us-east-1 --resourcesi-XXXXX --tags Key=Developer Name,Value=XXXXX Key=Resource Group,Value=my_custom_tag_1
aws ec2 create-tags --region us-east-1 --resourcesi-XXXX --tags Key=Developer Name,Value=XXXXX Key=Resource Group,Value=my_custom_tag_2

Eu tentei carregar as linhas do arquivo em uma matriz e incluir o índice em sed replace.

sed "s|${file2array[0]}|${file1array[0]}|g" file3.txt

Mas isso retorna um erro "sem expressão regular anterior". Eu também tentei escrever os índices da matriz para variáveis exclusivas com um loop for e usando a mesma abordagem acima com as variáveis

sed "s|$var2|$var1|g" file3.txt

Isso também falha

Curiosamente,

sed "s|${file2array[0]}|customtext}|g" file3.txt

falha, mas

sed "s|customtext|${file1array[0]}|g" file3.txt

é bem-sucedido.

Qualquer ajuda é muito apreciada. Estou trabalhando nisso há dezenas de horas agora.

    
por Jeff Carson 21.09.2016 / 06:21

2 respostas

1

Tente:

awk 'FNR==NR{a[FNR]=$0; next} NR<=length(a)+FNR{b[FNR]=$0; next} {for (i=1;i<=length(a);i++) gsub(a[i], b[i])} 1' file2 file1 file3

Por exemplo:

$ awk 'FNR==NR{a[FNR]=$0; next} NR<=length(a)+FNR{b[FNR]=$0; next} {for (i=1;i<=length(a);i++) gsub(a[i], b[i])} 1' file2 file1 file3
aws ec2 create-tags --region us-east-1 --resourcesi-XXXXX --tags Key=Developer Name,Value=XXXXX Key=Resource Group,Value=my_custom_tag_1
aws ec2 create-tags --region us-east-1 --resourcesi-XXXX --tags Key=Developer Name,Value=XXXXX Key=Resource Group,Value=my_custom_tag_2

Como funciona

  • FNR==NR{a[FNR]=$0; next}

    Isto salva todas as linhas no arquivo2 no array a .

    FNR é o número de linhas lidas no arquivo atual. NR é o número de linhas lidas no total. Assim, se FNR==NR , estamos lendo o primeiro arquivo nomeado, file2 . a[FNR]=$0 adiciona a linha atual, denotada $0 , na matriz a sob a chave FNR.

    O comando next diz ao awk para ignorar os comandos restantes e recomeçar na linha next .

  • NR<=length(a)+FNR{b[FNR]=$0; next}

    Isso salva todas as linhas do arquivo1 no array b .

    Aqui, usamos um teste semelhante, NR<=length(a)+FNR , para determinar se estamos lendo o segundo arquivo. b[FNR]=$0 adiciona a linha atual, denotada $0 , na matriz b sob a chave FNR.

    O comando next diz ao awk para ignorar os comandos restantes e recomeçar na linha next .

  • for (i=1;i<=length(a);i++) gsub(a[i], b[i])

    Se chegarmos aqui, estamos lendo o terceiro arquivo. Isso substitui qualquer texto que corresponda a uma linha no arquivo2 pelo texto correspondente do arquivo1.

    O loop for (i=1;i<=length(a);i++) faz um loop sobre o número da linha de cada linha na matriz a .

    gsub(a[i], b[i]) substitui qualquer ocorrência de texto a[i] pelo texto b[i] .

    Observe que o texto no arquivo2 é tratado como uma expressão regular. Se você precisar ter algum caractere regex ativo nesse arquivo, ele deverá ter escape.

  • 1

    Esta é a senha curta do awk para imprimir a linha.

por 21.09.2016 / 06:34
0

Eu escreveria

awk '
  BEGIN { FS = OFS = "=" }
  FILENAME == "file1" {
    tag[FNR] = $0
  }
  FILENAME == "file2" {
    str[$0] = FNR
  }
  FILENAME == "file3" {
    if ($NF in str) $NF = tag[str[$NF]]
    print
  }
' file1 file2 file3

Eu acho que é bastante simples. Deixe-me saber se você tiver dúvidas.

    
por 21.09.2016 / 21:53