How to create files named after lines in a text file under Linux
I have a text file which contains a list of items (one for each line) and I need to create, in a given directory, a file for every entry in the said list; each one of these files should be named with a string in the said list. Also, if possible, after the string contained in the text file, a custom text should be appended to the filenames.
Which commands should I use to do that from the command line? I suppose that cat
, grep
and touch
(and maybe xargs
?) should be involved in the process, but after a few trials I still can't find the correct syntax.
Can someone enlighten me about this?
Say you have list.txt
like this:
file 1
file 2
file 3
You can achieve what you want with:
while read FILE; do touch "${FILE} some string"; done < list.txt
So you've got a file list
which contains:
this
that
the-other
and you want to create, for each line in that file, a file with the name given on that line. That's pretty easy – if and only if each line consists just of a single word:
cat list | xargs touch --
(The --
tells touch
not to try to parse anything after it as an argument; without it, if you have filenames like -this
, the leading -
will confuse touch into thinking 't', 'h', 'i', and 's' are meant as arguments, rather than parts of the literal filename to touch.)
That's the simple case taken care of, but it's not what you asked; if you want the filename to contain some text beyond what's specified on the lines in list
, things get more complicated; xargs can't do that sort of interpolation. Instead, you'd need something like the following (which requires that your shell is bash
, as is standard on most systems):
for file in `cat list`; do touch -- $file-customtext; done
Beware that this still only works if each line consists of a single word only. In this command, $file
is replaced by the filename specified on a given line in list
; everything around it is taken literally, so this command with the list
contents above would create the following files:
this-customtext
that-customtext
the-other-customtext
You can replace '-customtext' with whatever you like, of course, and you can also have a prefix as well as a suffix; if you instead had do touch -- some-$file-text
, for example, it'd work just as well, and result in files named some-this-text
&c.
Now, then, supposing the contents of list
aren't so simple -- specifically, that they contain spaces, non-word characters, or other things that the shell won't interpret properly. If you ask three people what they'd recommend in this case, you'd likely get five answers; I'm a Perl hacker, so my answer is Perl. Specifically, let's assume a list
that contains:
This is the first line
of three (three?) lines
in the list file.
The way I'd do this would be:
cat list | perl -ne'chomp; system(qq|touch -- "custom $_ text"|)'
Which produces the resulting files:
custom This is the first line text
custom of three (three?) lines text
custom in the list file. text
The custom text in this case can be whatever you like, spaces and all, so long as it contains neither "
(which will confuse touch
) nor '
(which will confuse perl
); in the Perl command, $_
represents the contents of a given line from list
, and custom text belongs either before or after it, but within the double quotes. (Custom text outside the double quotes will be regarded by touch
as a separate filename, which will be literally created unless it contains something that'll cause touch
to error out.)