问题
Trying to figure out how to iterate through a .txt
file (filemappings.txt) line by line, then split each line using tab
(\t
) as a delimiter so that we can create the directory specified on the right of the tab (mkdir -p
).
Reading filemappings.txt and then splitting each line by tab
server/ /client/app/
server/a/ /client/app/a/
server/b/ /client/app/b/
Would turn into
mkdir -p /client/app/
mkdir -p /client/app/a/
mkdir -p /client/app/b/
Would xargs
be a good option? Why or why not?
回答1:
cut -f 2 filemappings.txt | tr '\n' '\0' | xargs -0 mkdir -p
xargs -0 is great for vector operations.
回答2:
You already have an answer telling you how to use xargs
. In my experience xargs
is useful when you want to run a simple command on a list of arguments that are easy to retrieve. In your example, xargs
will do nicelly. However, if you want to do something more complicated than run a simple command, you may want to use a while
loop:
while IFS=$'\t' read -r a b
do
mkdir -p "$b"
done <filemappings.txt
In this special case, read a b
will read two arguments separated by the defined IFS
and put each in a different variable. If you are a one-liner lover, you may also do:
while IFS=$'\t' read -r a b; do mkdir -p "$b"; done <filemappings.txt
In this way you may read multiple arguments to apply to any series of commands; something that xargs
is not well suited to do.
Using read -r
will read a line literally regardless of any backslashes in it, in case you need to read a line with backslashes.
Also note that some operating systems may allow tabs as part of a file or directory name. That would break the use of the tab as the separator of arguments.
回答3:
As others have pointed out, \t
character could also be a part of the file or directory name, and the following command may fail. Assuming the question represents the true form of the input file, one can use:
$ grep -o -P '(?<=\t).*' filemappings.txt | xargs -d'\n' mkdir -p
It uses -P
perl-style regex to get words after the \t
(TAB) character, then use -d'\n'
which provides all relevant lines as a single input to mkdir -p
.
回答4:
sed -n '/\t/{s:^.*\t\t*:mkdir -p ":;s:$:":;p}' filemappings.txt | bash
sed -n
: only work with lines that containstab
(delimiter)s:^.*\t\t*:mkdir -p :
: change all things from line beggning totab
tomkdir -p
| bash
: tellbash
to create folders
回答5:
With GNU Parallel it looks like this:
parallel --colsep '\t' mkdir -p {2} < filemapping.txt
来源:https://stackoverflow.com/questions/48305724/bash-script-to-mkdir-on-each-line-of-a-file-that-has-been-split-by-a-delimiter