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?
touch
name__:while read line; do touch "$line.txt"; done <in
while read line; [...]; done <in
: Ceci exécute read
jusqu'à ce que read
retourne lui-même 1
, ce qui se produit lorsque la fin du fichier est atteinte; l'entrée pour read
est lue à partir d'un fichier nommé in
dans le répertoire de travail en cours et non à partir du terminal en raison de la redirection <in
;touch "$line.txt"
: Ceci exécute touch
sur la valeur développée de $line.txt
, qui est le contenu de line
suivi de .txt
; touch
créera le fichier s'il n'existe pas et mettra à jour son heure d'accès s'il existe;xargs
+ touch
name__:xargs -a in -I name touch name.txt
-a in
: oblige xargs
à lire son entrée dans un fichier nommé in
dans le répertoire de travail en cours;-I name
: permet à xargs
de remplacer chaque occurrence de name
par la ligne d'entrée actuelle dans la commande suivante;touch name
: Lance touch
sur la valeur remplacée de name
name__; 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
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
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 =)
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