Como você salva um regex complexo para várias reutilizações no sed?

10

Ao usar sed , muitas vezes, crie expressões regulares complicadas e complexas que preciso corresponder duas vezes em um arquivo. Existe uma maneira de eu salvar este regex e apenas referenciá-lo duas vezes?

Talvez algo parecido com isso?

sed ' complicated_regex=/^(([a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})?)+$/
s/complicated_regex:complicated_regex/simple-output/
' my_file

Atualização: Uma resposta apresentou a solução de usar uma variável bash. Isso não funciona. Dado um test.txt .

#test.txt
foo bar
bar foo

E o script

#!/bin/bash

VALUE='foo \([a-z]\+\)'

sed 's/"${VALUE}"/foo happy /' test.txt

Isso deve produzir a saída

foo happy bar
bar foo

Mas, em vez disso, recebo o erro

sed: -e expression #1, char 24: invalid reference  on 's' command's RHS
    
por Cory Klein 21.09.2011 / 20:32

2 respostas

5

Você pode usar variáveis do shell:

complicated_regex='(([a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})?)+'
sed s/^"$complicated_regex":"$complicated_regex"\$/'simple-output'/ my_file

Não tenho certeza sobre o que você quis dizer com $i , mas talvez seja necessário colocá-lo fora de aspas simples:

complicated_regex='(([a-f0-9]{32})+([a-zA-Z0-9=]{{'"$i"'}})?)+'
    
por 21.09.2011 / 20:53
0

A maneira mais fácil de inserir um valor de variável do shell em sed e não se preocupar com a maneira como o escape da barra invertida precisará ser alterada para o resto do script sed é colocar tudo em cotações simples exceto a variável, e coloque isso entre aspas duplas.

Todos os exemplos de código a seguir pressupõem: VALUE='foo \([a-z]\+\)'

O seguinte código quebrado falha porque a variável VALUE não está expandida:

sed 's/"${VALUE}"/foo happy /' test.txt

O seguinte código quebrado falha porque a barra invertida em é comido pelo shell (porque está entre aspas duplas em vez de aspas simples) antes de sed vê-lo:

sed "s/${VALUE}/foo happy /" test.txt

O código a seguir funciona conforme o esperado:

sed 's/'"${VALUE}"'/foo happy /' test.txt

O seguinte código também funciona:

sed "s/${VALUE}/foo happy \1/" test.txt

O mesmo acontece com o seguinte:

sed s/"${VALUE}"/foo\ happy\ \1/ test.txt

Mas por que ficar complicado? Aspas simples em torno de um script sed tornam tudo muito mais claro, especialmente para os gurus que não utilizam scripts de shell que lêem seu código. Minha maneira preferida é, novamente, abandonar as aspas simples para aspas duplas apenas para a expansão da variável e voltar para aspas simples:

sed 's/'"${VALUE}"'/foo happy /' test.txt
    
por 19.01.2016 / 20:57