Eu tenho uma lista de nomes de arquivos dentro de um arquivo chamado list_of_files.txt
.
Eu quero copiar o conteúdo de cada arquivo nessa lista para outro arquivo chamado all_compounds.sdf
.
Como devo fazer isso na linha de comando?
Eu tenho uma lista de nomes de arquivos dentro de um arquivo chamado list_of_files.txt
.
Eu quero copiar o conteúdo de cada arquivo nessa lista para outro arquivo chamado all_compounds.sdf
.
Como devo fazer isso na linha de comando?
Respostas:
Não use simples substituição de comando para obter nomes de arquivos (que podem facilmente quebrar com espaços e outros caracteres especiais). Use algo como xargs
:
xargs -d '\n' -a list_of_files.txt cat > all_compounds.sdf
Ou um while read
loop:
while IFS= read -r file; do cat "$file"; done < list_of_files.txt > all_compounds.sdf
Para usar a substituição de comandos com segurança, defina pelo menos IFS
apenas a nova linha e desative o globbing (expansão de curinga):
(set -f; IFS=$'\n'; cat $(cat list_of_files.txt) > all_compounds.sdf)
Os parênteses circundantes ()
devem executar isso em um subshell, para que seu shell atual não seja afetado por essas alterações.
Maneira rápida e suja ...
cat $(cat list_of_files.txt) >> all_compounds.sdf
Observe: isso só funciona se os nomes de arquivos da sua lista forem muito bem comportados - as coisas darão errado se houver espaços, novas linhas ou caracteres que tenham um significado especial para o shell - use esta resposta para obter resultados confiáveis)
cat
con cat enates files. Também imprime seu conteúdo.command2 $(command1)
você pode passar a saída de command1
( cat list...
) para command2
( cat
) que concatena os arquivos.Em seguida, use o redirecionamento >>
para enviar a saída para um arquivo em vez de imprimir para stdout. Se você quiser ver a saída, use tee
:
cat $(cat list_of_files.txt) | tee -a all_compounds.sdf
(Eu usei em >>
vez de >
e tee
com a -a
opção caso seu arquivo já exista - isso é anexado ao arquivo em vez de sobrescrevê-lo, se ele já existir)
cat
a lista inteira será obtida como um argumento.
Embora o GNU awk
seja um utilitário de processamento de texto, ele permite executar comandos de shell externos via system()
chamada. Podemos utilizar isso para nossa vantagem da seguinte forma:
$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt
A idéia aqui é simples: lemos o arquivo linha por linha e, em cada linha, criamos uma string formatada cat "File name.txt"
, que é então passada para system()
.
E aqui está em ação:
$ ls
file1.txt file2.txt file3 with space.txt file_list.txt
$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt
Hi, I'm file2
Hi, I'm file1
Hi, I'm file3
Então, já fizemos a grande parte da tarefa - imprimimos todos os arquivos da lista. O resto é simples: redirecione a saída final para o arquivo com o >
operador no arquivo de resumo.
awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt > output.txt
"$(cat list_of_files.txt)"