Lettura di righe da un file di testo e creazione di un file di testo per ciascun nome su ciascuna riga

21

Diciamo che ho un file di testo come:

john
george
james
stewert

con ogni nome su una riga separata.

Voglio leggere le righe di questo file di testo e creare un file di testo per ogni nome, ad esempio: john.txt , george.txt ecc.

Come posso farlo in Bash?

    
posta levato 22.11.2015 - 15:34
fonte

4 risposte

17

# 1 Utilizzo di Bash + touch :

while read line; do touch "$line.txt"; done <in
  • while read line; [...]; done <in : esegue read fino a quando read restituisce 1 , che si verifica quando viene raggiunta la fine del file; l'input per read viene letto da un file denominato in nella directory di lavoro corrente anziché dal terminale a causa del reindirizzamento <in ;
  • touch "$line.txt" : esegue touch sul valore espanso di $line.txt , che è il contenuto di line seguito da .txt ; touch creerà il file se non esiste e aggiornerà il tempo di accesso se esistente;

# 2 Utilizzo di xargs + touch :

xargs -a in -I name touch name.txt
  • -a in : rende xargs letto il suo input da un file chiamato in nella directory di lavoro corrente;
  • -I name : rende xargs sostituisce ogni occorrenza di name con la riga corrente di input nel seguente comando;
  • touch name : esegue touch sul valore sostituito di name ; creerà il file se non esiste e aggiornerà il tempo di accesso se esistente;
% 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
    
risposta data kos 22.11.2015 - 15:49
fonte
18

In questo caso particolare, dove hai solo una parola per riga, puoi anche fare:

xargs touch < file

Notare che questo si interromperà se i nomi dei file possono contenere spazi. In questi casi, usa invece:

xargs -I {} touch {} < file

Solo per divertimento, ecco un paio di altri approcci (entrambi possono gestire nomi di file arbitrari, comprese le linee con spazi):

  • Perl

    perl -ne ''touch "$_"'' file
    
  • Awk

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

Si noti che su Linux e sistemi simili, l'estensione è facoltativa per la stragrande maggioranza dei file. Non c'è motivo di aggiungere un'estensione .txt a un file di testo. Sei libero di farlo ma non fa alcuna differenza. Quindi, se vuoi comunque l'estensione, usa uno dei seguenti:

xargs -I {} touch {}.txt < file
perl -ne ''touch "$_.txt"'' file
awk '{printf "" > $0".txt"}' file 
    
risposta data terdon 22.11.2015 - 17:58
fonte
7

Anche AWK è appropriato per questo compito:

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

Un altro modo, tee . Si noti che questo approccio si interromperà se una riga contiene più di una stringa nella lista file.

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


testerdir:$ ls
filelist  george  james  john  stewert

In alternativa, anche </dev/null tee $(cat filelist) può essere fatto, se vuoi evitare le tubazioni

Approccio

cp /dev/null (Come ho dimostrato, funziona con nomi di file che contengono spazi):

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
    
risposta data Sergiy Kolodyazhnyy 22.11.2015 - 18:06
fonte
7
% Bl0ck_qu0te%

Diciamo che ho una risposta ;)

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

Impermeabile anche con spazi e con un suffisso =)

    
risposta data A.B. 22.11.2015 - 18:04
fonte

Leggi altre domande sui tag