web-dev-qa-db-fra.com

Lire les lignes d'un fichier texte et créer un fichier texte pour chaque nom sur chaque ligne

Disons que j'ai un fichier texte comme:

john
george
james
stewert

avec chaque nom sur une ligne séparée.

Je veux lire les lignes de ce fichier texte et créer un fichier texte pour chaque nom, par exemple: john.txt, george.txt etc.

Comment puis-je faire cela dans Bash?

21
levato

# 1 Utilisation de Bash + touchname__:

while read line; do touch "$line.txt"; done <in
  • while read line; [...]; done <in: Ceci exécute readjusqu'à ce que readretourne lui-même 1, ce qui se produit lorsque la fin du fichier est atteinte; l'entrée pour readest lue à partir d'un fichier nommé indans le répertoire de travail en cours et non à partir du terminal en raison de la redirection <in;
  • touch "$line.txt": Ceci exécute touchsur la valeur développée de $line.txt, qui est le contenu de linesuivi de .txt; touchcréera le fichier s'il n'existe pas et mettra à jour son heure d'accès s'il existe;

# 2 Utilisation de xargs+ touchname__:

xargs -a in -I name touch name.txt
  • -a in: oblige xargsà lire son entrée dans un fichier nommé indans le répertoire de travail en cours;
  • -I name: permet à xargsde remplacer chaque occurrence de namepar la ligne d'entrée actuelle dans la commande suivante;
  • touch name: Lance touchsur la valeur remplacée de namename__; il créera le fichier s'il n'existe pas et mettra à jour son heure d'accès s'il existe;
% ls
in
% cat in
john
george
james
stewert
% while read line; do touch "$line.txt"; done <in
% ls
george.txt  in  james.txt  john.txt  stewert.txt
% rm *.txt
% xargs -a in -I name touch name.txt
% ls
george.txt  in  james.txt  john.txt  stewert.txt
18
kos

Dans ce cas particulier, où vous n'avez qu'un seul mot par ligne, vous pouvez aussi faire:

xargs touch < file

Notez que cela se cassera si vos noms de fichiers peuvent contenir des espaces. Dans ce cas, utilisez plutôt ceci:

xargs -I {} touch {} < file

Juste pour le plaisir, voici deux autres approches (les deux peuvent gérer des noms de fichiers arbitraires, y compris des lignes avec des espaces):

  • Perl

    Perl -ne '`touch "$_"`' file
    
  • Awk

    awk '{printf "" > $0}' file 
    

Notez que sur Linux et les systèmes similaires, l’extension est facultative pour la grande majorité des fichiers. Il n'y a aucune raison d'ajouter une extension .txt à un fichier texte. Vous êtes libre de le faire, mais cela ne fait aucune différence. Donc, si vous voulez quand même l'extension, utilisez l'une des options suivantes:

xargs -I {} touch {}.txt < file
Perl -ne '`touch "$_.txt"`' file
awk '{printf "" > $0".txt"}' file 
18
terdon

Disons que j'ai un fichier texte…

Disons que j'ai une réponse ;)

awk '{system("touch \""$0".txt\"")}' file

Imperméable également avec des espaces et avec un suffixe =)

7
A.B.

AWK est également approprié pour cette tâche:

testerdir:$ awk '{system("touch "$0)}' filelist

testerdir:$ ls
filelist  george  james  john  stewert

testerdir:$ awk '{system("touch "$0".txt")}' filelist                          

testerdir:$ ls
filelist  george.txt  james.txt  john.txt  stewert.txt
george    james       john       stewert

Une autre façon, tee. Notez que cette approche sera rompue si une ligne contient plus d'une chaîne dans la liste de fichiers.

testerdir:$ echo "" | tee $(cat filelist)


testerdir:$ ls
filelist  george  james  john  stewert

Vous pouvez également utiliser </dev/null tee $(cat filelist) si vous souhaitez éviter les tuyaux.

cp /dev/null (Comme je le démontre, cela fonctionne avec les noms de fichiers contenant des espaces):

testerdir:$ cat filelist | xargs -I {}  cp /dev/null  "{}"                     

testerdir:$ ls
filelist  FILE WITH SPACES  george  james  john  stewert

testerdir:$ ls FILE\ WITH\ SPACES                                              
FILE WITH SPACES
7