Ubuntu – Create directories with a name from txt file which contain ‘/’ character

bashcommand linedirectorytext processing

I have a .txt file that contains a text like this

A1/B1/C1
A2/B2/C2 
A3/B3/C3

I want a script that reads the .txt file for each line then create a directory based on the first word (A1, A2, A3)

I have created script like this:

file="test.txt"
while IFS='' read -r line
do
    name="line"
    mkdir -p $line
done <"$file"

While I run it, it creates directory A1 then it also create sub-directories B1 and C1. the same happens for another line (A2* and A3*)

What should I do to create only A1, A2, A3 directories?

I don't want to make the name like A1/B1/C1 with '/' character in it.
I just want to take the word before '/' character and make it directory name.
Just "A1" "A2" "A3".

Best Answer

You can just cut the 1st slash-delimited 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 Install 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.