Create directories with a name from txt file which contain '/' character
You can just cut
the 1
st slash-d
elimited field of each line and give the list to mkdir
:
mkdir $(<dirlist.txt cut -d/ -f1)
Example run
$ cat dirlist.txt
A1/A2/A3
B1/B2/B3
C1/C2/C3
$ ls
dirlist.txt
$ mkdir $(<dirlist.txt cut -d/ -f1)
$ ls
A1 B1 C1 dirlist.txt
You may run into ARG_MAX problems if your list holds a huge number of directory names, in this case use GNU parallel
or xargs
as follows:
parallel mkdir :::: <(<dirlist.txt cut -d/ -f1)
xargs -a<(<dirlist.txt cut -d/ -f1) mkdir
While parallel
has it covered, the xargs
approach won’t work if the directory names contain spaces – you can either use \0
as the line delimiter or simply instruct xargs
to only split the input on newline characters (as proposed by Martin Bonner) instead:
xargs -0a<(<dirlist.txt tr \\{n,0} | cut -d/ -f1 -z) mkdir # \\{n,0} equals \\n \\0
xargs -d\\n -a<(<dirlist.txt cut -d/ -f1) mkdir
In case any of the fields contains a newline character one would need to identify the “true” line endings and replace only those newline characters with e.g. \0
. That would be a case for awk
, but I feel it’s too far fetched here.
You need to set your IFS='/'
for read
and then assign each first field into separate variable first
and the rest of the fields into variable rest
and just work on first field's value (Or you can read -ar array
to a single array and use "${array[0]}"
for the first field's value. ):
while IFS='/' read -r first rest;
do
echo mkdir "$first"
done < test.txt
Or in single line for those who like it:
<test.txt xargs -d'\n' -n1 sh -c 'echo mkdir "$'{1%%/*}'"' _
Or create all directories in one-go:
<test.txt xargs -d'\n' bash -c 'echo mkdir "$'{@%%/*}'"' _
The ANSI-C Quoting $'...'
is used to deal with directory names containing special characters.
Note that the _
(can be any character or string) at the end will be argv[0] to the bash -c '...'
and the $@
will contains rest of the parameters starting from 1; without that in second command the first parameter to the mkdir
will be lost.
In ${1%%/*}
using shell (POSIX sh/bash/Korn/zsh) parameter substitution expansion, removes longest possible match of a slash followed by anything till the end of the parameter passing into it which is a line that read by xargs;
P.s:
- Remove
echo
in front of themkdir
to create those directories. - Replace
-d'\n'
with-0
if your list is separated with NUL characters instead of a\n
ewline (supposed there is/are embedded newline in your directory name).
Contents of test.txt
:
A 12"x4" dir/B b/C c
A1/B1/C1
A2/B2/C2
A3/B3/C3
Script to create A[123]
folders:
file="test.txt"
while read -r line ; do
mkdir "${line%%/*}"
done < "$file"
Output of ls
:
A 12"x4" dir
A1
A2
A3