Leyendo líneas de un archivo de texto y creando un archivo de texto para cada nombre en cada línea

21

Digamos que tengo un archivo de texto como:

john
george
james
stewert

con cada nombre en una línea separada.

Quiero leer las líneas de este archivo de texto y crear un archivo de texto para cada nombre, como: john.txt , george.txt etc.

¿Cómo puedo hacer esto en Bash?

    
pregunta levato 22.11.2015 - 14:34

4 respuestas

17

# 1 utilizando Bash + touch :

while read line; do touch "$line.txt"; done <in
  • while read line; [...]; done <in : esto ejecuta read hasta que read devuelva 1 , lo que sucede cuando se llega al final del archivo; la entrada para read se lee desde un archivo llamado in en el directorio de trabajo actual en lugar de hacerlo desde el terminal debido a la redirección de <in ;
  • touch "$line.txt" : esto ejecuta touch en el valor expandido de $line.txt , que es el contenido de line seguido de .txt ; touch creará el archivo si no existe y actualizará su tiempo de acceso si existe;

# 2 utilizando xargs + touch :

xargs -a in -I name touch name.txt
  • -a in : hace que xargs lea su entrada de un archivo llamado in en el directorio de trabajo actual;
  • -I name : hace que xargs reemplace cada aparición de name con la línea de entrada actual en el siguiente comando;
  • touch name : ejecuta touch en el valor reemplazado de name ; creará el archivo si no existe y actualizará su tiempo de acceso si 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
    
respondido por el kos 22.11.2015 - 14:49
18

En este caso particular, donde solo tiene una palabra por línea, también puede hacerlo:

xargs touch < file

Tenga en cuenta que esto se romperá si los nombres de sus archivos pueden contener espacios. Para tales casos, use esto en su lugar:

xargs -I {} touch {} < file

Solo por diversión, aquí hay un par de otros enfoques (los cuales pueden manejar nombres de archivos arbitrarios, incluidas las líneas con espacios):

  • Perl

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

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

Tenga en cuenta que en Linux y sistemas similares, la extensión es opcional para la gran mayoría de archivos. No hay razón para agregar una extensión .txt a un archivo de texto. Eres libre de hacerlo, pero no hace ninguna diferencia. Por lo tanto, si desea la extensión de todos modos, use una de:

xargs -I {} touch {}.txt < file
perl -ne ''touch "$_.txt"'' file
awk '{printf "" > $0".txt"}' file 
    
respondido por el terdon 22.11.2015 - 16:58
7

AWK también es apropiado para esta tarea:

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

Otra forma, tee . Tenga en cuenta que este enfoque se interrumpirá si una línea contiene más de una cadena en la lista de archivos.

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


testerdir:$ ls
filelist  george  james  john  stewert

Alternativamente, también se puede hacer </dev/null tee $(cat filelist) , si desea evitar la canalización

enfoque cp /dev/null (como demuestro, esto funciona con nombres de archivos que contienen espacios):

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
    
respondido por el Sergiy Kolodyazhnyy 22.11.2015 - 17:06
7
  

Digamos que tengo un archivo de texto ...

Digamos, tengo una respuesta ;)

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

Impermeable también con espacios y con un sufijo =)

    
respondido por el A.B. 22.11.2015 - 17:04

Lea otras preguntas en las etiquetas