Concatenando arquivos em um diretório e localizando o número total de linhas

0

No bash:

Estou tentando mesclar todos os arquivos em um diretório e, em seguida, contar o número total de linhas usando um único comando. Eu percebo que eu posso usar | para canalizar dois comandos:

! cat /data/files *.txt >> mergedfile.txt | wc -l ~/data/files/mergedfile.txt

No entanto, isso não parece funcionar. Eu estou usando bash e rodando em iPython (assim o! Na frente).

    
por John Smith 11.09.2017 / 03:11

2 respostas

0

Sua pergunta é um pouco confusa:

  • Você está usando ! para representar seu prompt de shell? Isso é atípico.
  • Você está falando sobre todos os arquivos .txt no diretório /data/files ? Para fazer isso, você deve dizer /data/files/*.txt . Se você quer dizer algo mais por /data/files *.txt , por favor explique.
  • >> mergedfile.txt irá anexar os arquivos a mergedfile.txt , se já existe. É isso que você quer? Se você quiser algo assim, você deve dizer isso em sua pergunta.

De qualquer forma, conforme declarado da Arrow em um comentário , A solução simples e óbvia é substituir o | por um ; , assim:

$ cat /data/files/*.txt >> mergedfile.txt; wc -l mergedfile.txt

Notas:

  • Como afirmei acima, >> acrescenta os arquivos a mergedfile.txt , se já existirem. Se você quiser ignorar (descartar) qualquer conteúdo anterior de mergedfile.txt , use > em vez de >> .
  • Se você fizer referência ao mesmo arquivo várias vezes, você deve fazer isso da mesma maneira todas as vezes. Usando um nome de caminho relativo uma vez e um nome de caminho absoluto na próxima vez é confuso e propenso a erros. (Você pode querer simplificar as coisas atribuindo o nome do arquivo a uma variável.)

Uma ligeira melhoria em relação ao acima é:

$ cat /data/files/*.txt > mergedfile.txt  &&  wc -l mergedfile.txt

com && em vez de ; . Isso faz com que o comando wc -l seja executado somente se o comando cat for bem-sucedido.

Cada uma das linhas de comando acima é caracterizada como uma "lista de comandos", contendo dois “pipelines” (embora não existam tubos reais envolvidos). Se você quiser fazer isso como um único "pipeline", faça isso:

$ cat /data/files/*.txt | tee mergedfile.txt | wc -l

que conta as linhas enquanto concatena os arquivos, eliminando a necessidade de ler o arquivo de saída. Se você deseja anexar a um mergedfile.txt existente, use tee -a .

    
por 11.09.2017 / 04:22
0

Deve ser:

! cat /data/files/*.txt >> mergedfile.txt && wc -l /data/files/mergedfile.txt

Seus comandos consistem em dois comandos - o primeiro é cat , que é enviado para um arquivo de texto por redirecionamento - o segundo é calcular o tamanho do arquivo resultante

Esses dois comandos precisam ser executados em sequência, desde que o primeiro tenha êxito. Então você usa && para encadear então. Depois que o stdout de cat for redirecionado para mergedfile.txt , o comando cat não produzirá stdout para canalizar para wc . Portanto, usar | está errado.

Como alternativa , você pode fazer:

! cat /data/files/*.txt | wc -l

, que é mais conciso e evita o uso de um arquivo temporário. Aqui, a saída de cat é enviada para wc para contar diretamente.

Observação , a primeira abordagem ao usar um arquivo temporário tem muitas desvantagens:

  • você precisa esvaziar o arquivo mergedfile.txt antes de executá-lo. Se você começou sem esse arquivo em seu diretório de trabalho, tudo bem. Mas é muito comum que você tenha tentado alguns comandos (como o errado que você usou) primeiro e então esqueça de esvaziar o arquivo temporário e executar o comando correto. Isso ainda resultará em uma resposta errada. De fato, se todas as linhas estiverem em /data/files/*.txt , você pode simplesmente usar > em vez de >> . Ele irá esvaziar o arquivo primeiro.
  • durante a execução do comando, o arquivo temporário pode ser alterado por outros usuários ou por você mesmo quando você quiser fazer algo em paralelo.

Além disso: se você precisar de mergedfile.txt para uso posterior, você pode usar tee para fazer uma cópia da saída:

! cat /data/files/*.txt | tee mergedfile.txt | wc -l

onde tee coloca seu stdin em mergedfile.txt e duplica para stdout .

    
por 12.09.2017 / 06:08

Tags