I'm trying to write a bash shell script that will read the data from a given (as an argument) file, and for each row in the file, make a sub-directory under the given (as an argument) directory.

The script is named studentDir and the input file is named studentInfo.txt.
Here is two lines from it:

Sara Smith Freshman Marketing
James Lucas Junior Engineering

On the command line the user would write the script name, the txt file name, and the directory where the new directories should be stored. I think it would be like this:

$ studentDir studentInfo.txt .

Which will create the sub-directories in the current directory.

The directories should be named LLLLFF.
For example:


(The other info from the input file is not needed)

I think to get the names I would use:

DIRNAME=$(cut -d' ' -f2 | cut -c1-4 ; cut -d' ' -f1 | cut -c1-2) 
mkdir "$DIRNAME" 

But I'm not sure what command would create a directory for each row, and how I could do it recursively for each one.

  • Is your question how to iterate over each line in the file, or how to use the output from your cut command as the directory name? P.S. Recursion is rarely the answer (and in this case it is indeed not). Recursion is evil. Stay away from recursion :-)
    – phemmer
    Apr 21, 2014 at 4:17
  • Hmm the question is how to use the output from the cut command as the directory name. I just need to make sure it does it for every line of the text file
    – Lacey
    Apr 21, 2014 at 4:47
  • Do none of your users have a middle name?
    – terdon
    Apr 21, 2014 at 11:07

3 Answers 3


awk solution

awk '{print substr($2,1,4) substr($1,1,2)}' file

gives you the directory names.

mkdir $(awk '{print substr($2,1,4) substr($1,1,2)}' file)

creates the directories (if they are not too many). For huge numbers (10,000+) you can use:

awk '{print substr($2,1,4) substr($1,1,2)}' file | xargs --delimiter=\\n mkdir

bash solution

awk is not necessary, the shell can do that itself:

while read first last rest; do mkdir -p "${last:0:4}${first:0:2}"; done <file
  • I think I follow. I've never used awk though. Is there a way to do it in bash? And I can replace 'file' with $1 I believe? Since it would be the first command-line parameter?
    – Lacey
    Apr 21, 2014 at 4:35
  • @JackieLawrence file is the name of the file awk is supposed to read. Apr 21, 2014 at 4:42
  • Using the While commands, couldn't I replace 'echo' with mkdir? So it would create the directory with that name rather than outputting. and for the <file , does the name need to be specified within the script, or will it reference the file that the user inputs? Thats what I meant with the $1 earlier. The user can input the file that they want to use this script with.
    – Lacey
    Apr 21, 2014 at 5:01
  • @JackieLawrence echo was for my testing only, forgot to change that. file is a literal name. You can replace that by e.g. "$1" but I would always recommend to use something like "$file" instead in case the parameter definition of the script changes. Apr 21, 2014 at 5:24

You could use perl. Saying:

perl -lanE 'mkdir substr(@F[1],0,4) . substr(@F[0],0,2)' studentInfo.txt

would create the desired directories.

  • I haven't learned to use perl yet either. Is there a way to do it in bash?
    – Lacey
    Apr 21, 2014 at 4:49

Try this:

arr=($(cut -d ' ' -f1,2 < $*))
mkdir $(for ((i=0;i<${#arr[@]};i=i+2)); do echo ${arr[$i+1]:0:4}${arr[$i]:0:2}; done)

The first line will create an array with only the first 2 fields from the input. Each element in the array will have two fields (first, last). The second line will go through each element in the array and substitute each field according the requirement and make a new directory out of each new formed entry.

  • arr=($(cut -d ' ' -f1,2 < $*)) mkdir $(for ((i=0;i<${#arr[@]};i=i+2)); do echo ${arr[$i+1]:0:4}${arr[$i]:0:2}; done)
    – KB73
    Aug 3, 2016 at 15:40
  • Although this may be a correct answer, but because of its relative complexity, I would like to see an explanation of it.
    – Kusalananda
    Aug 3, 2016 at 18:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .