J'ai une liste de noms de fichiers dans un fichier appelé list_of_files.txt
.
Je veux copier le contenu de chaque fichier de cette liste dans un autre fichier appelé all_compounds.sdf
.
Comment dois-je procéder à partir de la ligne de commande?
J'ai une liste de noms de fichiers dans un fichier appelé list_of_files.txt
.
Je veux copier le contenu de chaque fichier de cette liste dans un autre fichier appelé all_compounds.sdf
.
Comment dois-je procéder à partir de la ligne de commande?
Réponses:
N'utilisez pas de substitution de commande simple pour obtenir les noms de fichiers (qui pourraient facilement rompre avec les espaces et autres caractères spéciaux). Utilisez quelque chose comme xargs
:
xargs -d '\n' -a list_of_files.txt cat > all_compounds.sdf
Ou une while read
boucle:
while IFS= read -r file; do cat "$file"; done < list_of_files.txt > all_compounds.sdf
Pour utiliser la substitution de commandes en toute sécurité, définissez au moins IFS
uniquement la nouvelle ligne et désactivez la globalisation (expansion avec caractères génériques):
(set -f; IFS=$'\n'; cat $(cat list_of_files.txt) > all_compounds.sdf)
Les parenthèses environnantes ()
doivent exécuter ceci dans un sous-shell, afin que votre shell actuel ne soit pas affecté par ces changements.
Façon rapide et sale ...
cat $(cat list_of_files.txt) >> all_compounds.sdf
Veuillez noter: cela ne fonctionne que si les noms de fichiers dans votre liste se comportent très bien - les choses iront mal s'ils ont des espaces, des nouvelles lignes ou des caractères qui ont une signification particulière pour le shell - utilisez plutôt cette réponse pour des résultats fiables)
cat
con cat enate les fichiers. Il imprime également leur contenu.command2 $(command1)
vous pouvez passer la sortie de command1
( cat list...
) à command2
( cat
) qui concatène les fichiers.Utilisez ensuite la redirection >>
pour envoyer la sortie vers un fichier au lieu d'imprimer vers stdout. Si vous voulez voir la sortie, utilisez tee
plutôt:
cat $(cat list_of_files.txt) | tee -a all_compounds.sdf
(J'ai utilisé à la >>
place de >
et tee
avec le -a
commutateur au cas où votre fichier existe déjà - cela s'ajoute au fichier au lieu de le remplacer, s'il existe déjà)
cat
obtient alors la liste entière en un seul argument.
Bien que GNU awk
soit un utilitaire de traitement de texte, il permet d'exécuter des commandes shell externes via system()
appel. 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 passée à 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à fait la majeure partie 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 récapitulatif.
awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt > output.txt
"$(cat list_of_files.txt)"