web-dev-qa-db-fra.com

Comment copier le contenu de chaque fichier d'une liste dans un autre fichier?

J'ai une liste de noms de fichiers dans un fichier appelé list_of_files.txt.

Je souhaite copier le contenu de chaque fichier de cette liste dans un autre fichier appelé all_compounds.sdf.

Comment dois-je faire cela à partir de la ligne de commande?

15
Ramita Rajaa

N'utilisez pas de substitution de commande simple pour obtenir les noms de fichiers (qui pourraient facilement se briser avec des espaces et d'autres caractères spéciaux). Utilisez quelque chose comme xargs:

xargs -d '\n' -a list_of_files.txt cat > all_compounds.sdf

Ou une boucle while read:

while IFS= read -r file; do cat "$file"; done < list_of_files.txt > all_compounds.sdf

Pour utiliser la substitution de commande en toute sécurité, définissez au moins IFS uniquement sur la nouvelle ligne et désactivez le mode de substitution (développement de caractère générique):

(set -f; IFS=$'\n'; cat $(cat list_of_files.txt) > all_compounds.sdf)

Les parenthèses environnantes () doivent être exécutées dans un sous-shell afin que votre Shell actuel ne soit pas affecté par ces modifications.

20
muru

Manière rapide et sale ...

cat $(cat list_of_files.txt) >> all_compounds.sdf

Remarque: Cela ne fonctionne que si les noms de fichiers de votre liste se comportent très bien. Les choses se passeront mal si elles ont des espaces, des nouvelles lignes ou tout autre caractère ont une signification particulière pour Shell - utilisez cette réponse à la place pour des résultats fiables)

Remarques

  • cat con cat énate les fichiers. Il imprime également leur contenu.
  • En utilisant la substitution de commande command2 $(command1), vous pouvez transmettre le résultat de command1 (cat list...) à command2 (cat), qui concatène les fichiers.
  • Utilisez ensuite la redirection >> pour envoyer la sortie dans un fichier au lieu de l’imprimer sur la sortie standard. Si vous voulez voir la sortie, utilisez plutôt tee:

    cat $(cat list_of_files.txt) | tee -a all_compounds.sdf
    

(J'ai utilisé >> au lieu de > et tee avec le commutateur -a au cas où votre fichier existe déjà - ceci est ajouté au fichier au lieu de l'écraser, s'il existe déjà)

14
Zanna

Bien que GNU awk soit un utilitaire de traitement de texte, il permet d'exécuter des commandes Shell externes via l'appel system(). Nous pouvons utiliser cela à notre avantage comme ceci:

$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt                                                        

L'idée ici est simple: nous lisons le fichier ligne par ligne et, à partir de chaque ligne, nous créons une chaîne formatée cat "File name.txt", qui est ensuite transmise à system().

Et le voici en action:

$ 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

Nous avons donc déjà effectué l'essentiel de la tâche: nous avons imprimé tous les fichiers de la liste. Le reste est simple: redirigez la sortie finale vers le fichier avec l’opérateur > dans le fichier de synthèse.

awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt > output.txt
4