Em um shell tipo Bourne ou rc
a='
' perl -pe 's/pattern/$ENV{a}$&/g' < abc.txt
passaria uma variável de ambiente a
para 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
diferente de '
a uma variável em shells semelhantes a Bourne, você pode usar:
a='x'
Então, para a barra invertida:
a='\'
Para nova linha:
a='
'
Para caracteres de controle como newline, mas isso seria ainda pior para backspace ou carriage-return, por exemplo, que torna o código menos legível.
O ksh93 introduziu uma nova forma de aspas $'...'
para especificar esses caracteres em um formulário com escape. Outros shells como bash
, zsh
, mksh
ou FreeBSD sh
copiaram e estenderam (como $'\uXXXX'
forma adicionada por zsh
) desde então.
Nesses shells, 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, por isso você não pode usá-lo em um script sh
portátil. Uma alternativa padrão é usar:
a=$(printf '\b')
para backspace, por exemplo, mas isso não funciona para newline, pois a substituição de comando ( $(cmd)
) retira caracteres de nova linha 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 notações de \n
em seu código, então você pode fazer:
perl -pe 's/pattern/\n$&/g' < abc.txt
A implementação GNU de sed
(e alguns outros atualmente) 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 comando s
em sed
tem que 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
Portanto, se você quiser inserir uma barra invertida e uma nova linha na frente de pattern
, será necessário:
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 variável a
:
a='\
' perl -pe 's/pattern/$ENV{a}$&/g' < abc.txt