
eu queria capturar \n em uma variável (suponha a) e substituir $a na frente do padrão de pesquisa em um arquivo (abc.txt)
alguém pode me sugerir a solução?
> cat abc.txt
hi how are you how is your health
> echo $a
\
saída esperada (padrão de pesquisa - how
)
hi \
how are you \
how is your health
Responder1
Em um shell tipo Bourne ou tipo rc
a='
' perl -pe 's/pattern/$ENV{a}$&/g' < abc.txt
passaria uma a
variável de ambiente perl
contendo um caractere de nova linha e perl
inseriria o conteúdo dessa variável antes de cada ocorrência de pattern
no conteúdo de abc.txt
.
Para atribuir qualquer caractere x
que não seja '
uma variável em shells do tipo Bourne, você pode usar:
a='x'
Então, para barra invertida:
a='\'
Para nova linha:
a='
'
Para caracteres de controle como nova linha, mas isso seria ainda pior para backspace ou retorno de carro, por exemplo, que torna o código menos legível.
ksh93 introduziu uma nova $'...'
forma de aspas para especificar esses caracteres em formato de escape. Outros shells como bash
, zsh
ou mksh
FreeBSD sh
o copiaram e estenderam (como o $'\uXXXX'
formulário adicionado por zsh
) desde então.
Nessas conchas, você pode usar:
a=$'\n' a=$'\b' a=$'\r' a=$'\\' a=$'\''
Para atribuir um caractere de nova linha, retrocesso, retorno de carro, barra invertida ou aspas simples.
Esse operador de cotação ainda não é padrão, portanto você não pode usá-lo em um sh
script portátil. Uma alternativa padrão é usar:
a=$(printf '\b')
para backspace, por exemplo, mas isso não funciona para nova linha, pois a substituição de comando ( $(cmd)
) remove os caracteres de nova linha à direita da saída de cmd
. É preciso recorrer a hacks como:
nl=$(printf '\n.'); nl=${nl%.}
(isto é, adicione um .
e remova-o depois) para preservá-lo.
Observe que perl
também entende essas \n
notações em seu código, então você pode fazer:
perl -pe 's/pattern/\n$&/g' < abc.txt
A implementação GNU sed
(e algumas outras hoje em dia) também suporta:
sed 's/pattern/\n&/g' < abc.txt
mas isso não é padrão. Normalmente, uma nova linha na parte de substituição do s
comando in sed
deve ser expressa com uma barra invertida seguida por uma nova linha, de modo que seria:
backslash='\' newline='
'
sed "s/pattern/$backslash$newline&/g" < abc.txt
Ou sem as variáveis:
sed 's/pattern/\
&/g' < abc.txt
Então, se quiser inserir uma barra invertida e uma nova linha na frente de pattern
, você precisa:
sed 's/pattern/\\\
&/g' < abc.txt
3 barras invertidas no total, duas para uma barra invertida literal e uma para a nova linha. Ou com perl
:
perl -pe 's/pattern/\\\n$&/g' < abc.txt
Ou com sua a
variável:
a='\
' perl -pe 's/pattern/$ENV{a}$&/g' < abc.txt
Responder2
Você também pode usar os próprios comandos bash usando:
cat abc.txt | sed -e 's/how/\nhow/g' | while read line; do echo "$line \\"; done