Reading lines from a text file and creating a text file for each name on each line
#1 Using Bash + touch
:
while read line; do touch "$line.txt"; done <in
-
while read line; [...]; done <in
: This runsread
untilread
itself returns1
, which happens when when the end of the file is reached; the input forread
is read from a file namedin
in the current working directory instead of from the terminal due to the<in
redirection; -
touch "$line.txt"
: This runstouch
on the expanded value of$line.txt
, which is the content ofline
followed by.txt
;touch
will create the file if not existing and update its access time if existing;
#2 Using xargs
+ touch
:
xargs -a in -I name touch name.txt
-
-a in
: makesxargs
read its input from a file namedin
in the current working directory; -
-I name
: makesxargs
replace every occurence ofname
with the current line of input in the following command; -
touch name
: Runstouch
on the replaced value ofname
; it will create the file if not existing and update its access time if existing;
% 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
In this particular case, where you only have a single word per line, you can also do:
xargs touch < file
Note that this will break if your file names can contain spaces. For such cases, use this instead:
xargs -I {} touch {} < file
Just for fun, here are a couple of other approaches (both of which can handle arbitrary file names, including lines with spaces):
-
Perl
perl -ne '`touch "$_"`' file
-
Awk
awk '{printf "" > $0}' file
Note that on Linux and similar systems, the extension is optional for the vast majority of files. There is no reason to add a .txt
extension to a text file. You are free to do so but it makes no difference at all. So, if you want the extension anyway, use one of:
xargs -I {} touch {}.txt < file
perl -ne '`touch "$_.txt"`' file
awk '{printf "" > $0".txt"}' file
AWK is also appropriate for this task:
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
Another way, tee
. Notice that this approach will break if a line contains more than one string in the filelist.
testerdir:$ echo "" | tee $(cat filelist)
testerdir:$ ls
filelist george james john stewert
Alternatively, </dev/null tee $(cat filelist)
can be done as well, if you want to avoid piping
cp /dev/null
approach (As I demonstrate this does work with filenames that contain spaces):
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
Let's say I have a text file …
Let's say, I have an answer ;)
awk '{system("touch \""$0".txt\"")}' file
Waterproof also with spaces and with a suffix =)