Estes são os comandos, reconhecidamente enigmáticos, sed
. Especificamente (de man sed
):
: label
Rótulo para os comandos b e t.t label
Se um s /// fez uma substituição bem sucedida desde o último linha de entrada foi lida e desde o último comando t ou T, então ramo para rotular; se label for omitido, ramifique para o final do script.n N Leia / acrescente a próxima linha de entrada no espaço padrão.
Assim, o script que você postou pode ser dividido em (espaços adicionados para legibilidade):
sed ':a; $!N; s/\n/string/; ta'
--- ---- ------------- --
| | | |--> go back ('t') to 'a'
| | |-------------> substitute newlines with 'string'
| |----------------------> If this is not the last line ('$!'), append the
| next line to the pattern space.
|----------------------------> Create the label 'a'.
Basicamente, o que isso está fazendo poderia ser escrito em pseudocódigo como
while (not end of line){
append current line to this one and replace \n with 'string'
}
Você pode entender isso um pouco melhor com um exemplo de entrada mais complexo:
$ printf "line1\nline2\nline3\nline4\nline5\n" | sed ':a;$!N;s/\n/string/;ta'
line1stringline2stringline3stringline4stringline5
Não sei ao certo por que o !$
é necessário. Tanto quanto eu posso dizer, você pode obter a mesma saída com
printf "line1\nline2\nline3\nline4\nline5\n" | sed ':a;N;s/\n/string/;ta'