Por que isso não funciona? “Ls * .txt | xargs cat all.txt ”(todos os arquivos em um único documento de texto)

19

Por que isso não funciona?

ls *.txt | xargs cat > all.txt

(Eu quero juntar o conteúdo de todos os arquivos de texto em um único arquivo 'all.txt'.) find com -exec também deve funcionar, mas eu realmente gostaria de entender a sintaxe xargs.

Obrigado

    
por ajo 28.09.2010 / 13:04

4 respostas

25

ls *.txt | xargs cat >> all.txt

pode funcionar um pouco melhor, já que seria anexado a todo o arquivo.txt em vez de criá-lo novamente após cada arquivo.

A propósito, cat *.txt >all.txt também funcionaria. : -)

    
por 28.09.2010 / 13:08
3

Se alguns dos seus nomes de arquivo contiverem ',' ou o espaço xargs falhará devido a problema do separador

Em geral, nunca execute xargs sem -0, pois ele voltará e o morderá algum dia.

Considere usar o GNU Parallel em vez disso:

ls *.txt | parallel cat > tmp/all.txt

ou se preferir:

ls *.txt | parallel cat >> tmp/all.txt

Saiba mais sobre o link do GNU Paralelo

    
por 28.09.2010 / 16:36
1

all.txt é um arquivo no mesmo diretório, então o gato fica confuso quando quer escrever do mesmo arquivo para o mesmo arquivo.

Por outro lado:

ls *.txt | xargs cat > tmp/all.txt

Isso lerá os arquivos de texto em seu diretório atual no arquivo all.txt em um subdiretório (não incluído em *.txt ).

    
por 28.09.2010 / 13:11
0

Você também pode se deparar com uma limitação de comprimento da linha de comando. Parte do motivo para usar xargs é que ele divide a entrada em partes seguras do tamanho da linha de comando. Então, imagine uma situação em que você tem centenas de milhares de arquivos .txt no diretório. ls *.txt falhará. Você precisaria fazer

ls | grep .txt$ |xargs cat > /some/other/path/all.txt

.txt$ neste caso é uma expressão regular que corresponde a tudo o que termina em .txt (por isso não é exatamente como *.txt , pois se você tiver um arquivo chamado atxt , *.txt não corresponderia a ele mas a expressão regular seria.)

O uso de outro caminho é porque, como outras respostas apontaram, o arquivo all.txt é correspondido pelo padrão *.txt , então haveria um conflito entre a entrada e a saída.

Observe que, se você tiver arquivos com ' em seus nomes (e isso pode ser a causa do erro unmatched single quote ), você deve fazer

ls | grep --null .txt$ | xargs -0 cat > /some/other/path/all.txt

A opção --null diz ao grep para usar a saída separada por um caractere -0 (null) em vez da nova linha padrão, e a opção %code% para 'xargs diz para esperar sua entrada no mesmo formato. Isso funcionaria mesmo se você tivesse nomes de arquivos com novas linhas neles.

    
por 07.07.2015 / 22:18

Tags