Existe um comando Unix para citar linhas de entrada?

4

Eu estou querendo saber se existe um comando de filtro para citar as linhas de entrada.

Então, quando a tubulação:

line number 1
line number 2
line number 3

para isso, você tem:

"line number 1"
"line number 2"
"line number 3"

Eu preciso deste comando para canalizar um fluxo de linhas para xargs para garantir que xargs trate line number 1 como um argumento e não como três. Tenho certeza de que também tem muitos outros usos.

Existe tal comando? Como é chamado?

    
por wefwefa3 15.09.2015 / 17:59

6 respostas

7

Eu ofereço a função quotemeta do Perl. Não bastante o que você pediu, porque ele escapa de espaços em vez de substituí-los por citações.

Mas, como benefício adicional, ele também lida com outros caracteres especiais (como * ):

perl -nle 'print quotemeta'

(Ou, como observado nos comentários, a forma mais curta: perl -ple '$_=quotemeta' )

Que leva suas linhas e as transforma em:

line\ number\ 1
line\ number\ 2
line\ number\ 3

Qual deve ter o mesmo resultado - assim como o tratamento:

Line number \"'rm -rf *'\"

E semelhantes tais travessuras :)

    
por 15.09.2015 / 18:31
7

Nenhum é projetado especificamente para isso, mas muitas ferramentas multifuncionais podem fazer isso:

  • sed 's/^/"/;s/$/"/'

  • perl -pe 's/^/"/;s/$/"/' ou perl -lne 'print "\"$_\""'

  • awk '{printf "\"%s\"\n",$0}'

  • while read -r line; do printf '"%s"\n' "$line"; done

(Tudo isso assume que a linha não contém aspas duplas. Se isso acontecer, ela quebrará xargs )

    
por 15.09.2015 / 18:05
4

Se em um sistema GNU, examine o argumento --delimiter para xargs . Como sua entrada é separada por novas linhas, você não precisa depender de citações nem usar ferramentas adicionais:

cat files.txt | xargs --delimiter=\n printf "<%s>"

Onde files.txt contém sua entrada:

line number 1
line number 2
line number 3

Dá a saída:

<line number 1><line number 2><line number 3>

NB: Você não precisa armazenar sua entrada em um arquivo e usar cat ; você pode, naturalmente, canalizar diretamente de outro programa. Eu usei cat no meu exemplo devido à sua onipresença e utilidade na criação de exemplos independentes como este.

Melhor ainda (e recomendado pelo manual xargs ) é que seu programa de saída separe as entradas pelo NUL ( --null ) em vez de uma nova linha, e use a opção --delimiter em vez de %code% , mas contanto que suas strings de entrada nunca contenham novas linhas, você concorda com a abordagem acima.

    
por 15.09.2015 / 19:09
3

Observe que você precisaria adicionar " no início e no fim e transformar " s em "\"" :

printf '%s\n' 'foo "bar" baz' 'biz' |
  sed 's/"/"\""/g;s/^/"/;s/$/"/' |
  xargs printf '<%s>\n'

saídas:

<foo "bar" baz>
<biz>
    
por 15.09.2015 / 18:49
3

No sistema GNU, com suporte ao shell $'...' :

xargs -d$'\n' printf '%s\n' <<\IN            
line number 1
line number 2
line number 3
IN

Com ferramentas padrão:

:|paste -d'"' - file - | xargs printf '%s\n'

Ambos assumiram que sua linha não continha citações incorporadas.

    
por 15.09.2015 / 18:09
3
{ echo "x1 x2 x3" ; echo "y1 y2 y3"; } | xargs -L1 echo

x1 x2 x3
y1 y2 y3

O -L1 usará cada linha separadamente

No entanto, a manpage está estragando:

A line ending with a space continues to the next non-empty line.

Veja aqui:

{ echo "x1 x2 x3 " ; echo "y1 y2 y3"; } | xargs -L1 echo

x1 x2 x3 y1 y2 y3
    
por 15.09.2015 / 22:28