O Shell remove as novas linhas finais. A solução alternativa comum é adicionar um caractere no final da substituição do comando e removê-lo.
x=$( echo a; echo ; echo :)
echo "${x%:}"
Quando eu quiser substituir, diga Dot
com
Dot
##empty line##
Eu faço isso:
sed 's/Dot/Dot\
/g'
Sim, uma nova linha literal, é assim que funciona no BSD sed
. Mas não consigo fazer o mesmo quando o sed
está entre parênteses. Exemplo de comando:
lol=$(echo $varcontaining something | sed 's/Dot/Dot\
/g')
Porque ele só será substituído por . (espaço em branco)
O Shell remove as novas linhas finais. A solução alternativa comum é adicionar um caractere no final da substituição do comando e removê-lo.
x=$( echo a; echo ; echo :)
echo "${x%:}"
E esses métodos mencionados neste Stackoverflow Q & A intitulado: Como faço para usar uma nova linha de reposição em um BSD sed? :
sed -e 's/ /\'$'\n/g'
Ou outro método mencionado onde você coloca a nova linha em uma variável da seguinte forma:
cr="
"
Em seguida, use a variável:
sed "s/ /\${cr}/g"
Provavelmente, a maneira mais eficaz de fazer isso - como eu considero - é com eval
. Se você quiser valores literais de uma expansão de shell, a maneira mais direta de obtê-los é a entrada literal - e a única maneira de obter isso da saída de um shell é alimentá-lo de volta.
Geralmente, é mais fácil trabalhar com '
aspas duras. A regra de cotação simples para uma '
com cotação incorreta '
é que ela não pode conter uma cotação difícil - a única maneira de obter uma interpretada em tal contexto é concatenar 2 ou mais cadeias entre aspas como ...
VAR='string'\''more string'
Dessa forma, a primeira string entre aspas termina na segunda aspa, a segunda string citada é apenas uma daspas duras com escape de barra invertida, e a terceira é a quarta aspa dura até o final.
E então o que eu poderia fazer se você fosse ...
eval "lol='$(nl='\
'; printf %s\n "$lol" |
sed "s/Dot/&$nl/g
s/'"'/&\&&/g
$s/$/'"'/
")"
Dessa forma, a mesma linha inicial que printf
adiciona ao valor do var é aquela que a substituição do comando retira - que também é o último caractere na saída porque o segundo ao último caractere é sempre uma citação difícil - e que delimita com segurança a instrução eval
porque sed
escapa de aspas duras que podem aparecer em sua entrada e há uma na parte superior da string.
E, a menos que você tenha valores enormes em suas variáveis de shell - o que também costuma ser uma má ideia -, algo assim provavelmente é o melhor caminho a seguir:
set -- "$lol"
while case "$1" in (*Dot*)
set -- "${1%Dot*}" "${1##*Dot}Dot
$2";;(*) ! lol=$1$2;; esac
do :; done
Você pode usar a nova linha \n
junto com o retorno de carro \r
. Eu não tenho BSD sed
para testar, mas funciona com o GNU sed
.
$ var=Dot
$ lol=$(echo $var | sed 's/Dot/Dot\n\r/g')
$ echo "$lol"
Dot
$
Se o BSD sed
não suportar \r
, outra solução (bastante feia) será imprimir \n\r
com echo -e
ou printf
:
lol=$(echo $var | sed "s/Dot/Dot\$(printf '\n\r')/g")
Tags text-processing sed shell