4

I have a text file with multiple rows. In every row I have the date in the following format:

12/2/2015
15/9/2013
08/3/2011
02/5/2005
.
.
.

I want to create a folder for every line in this text file using a simple for loop as follows:

#!/bin/bash -f
for f in $(cat ./file.txt ); do 
mkdir ${f}
done

This code didn't work because I have the character / in the date format. How can I create the folders and remove this character from the folder name at the same time? So the output folders names will be like this:

1222015
1592013
0832011
0252005
.
.
.
3
  • 5
    The month-day-year sorts wrong. Wouldn't you prefer year-month-day?
    – John1024
    Aug 7 '15 at 18:55
  • 1
    @John1024 The OP is using DMY, not MDY: there is no 15th month. Anyway, even YMD wouldn't sort right without an additional change: the month needs to have a leading zero, like the day already has, in order for that to work.
    – hvd
    Aug 7 '15 at 23:14
  • @hvd The leading zero is easy to add.
    – John1024
    Aug 7 '15 at 23:15
8

You can use a command like this:

sed -e 's/\///g' < file.txt | xargs mkdir

The sed command will strip the newlines from file.txt and the pipe to xargs will run mkdir for each line in the file.

An equivalent command (suggest by don_crissti) using tr instead of sed is:

tr -d / < file.txt | xargs mkdir
1
  • 1
    No prob. Yeah, many ways... though with unknown input this solution is still the best as it still works (the perl one should work too). Aug 7 '15 at 19:21
3

Rather than reinventing in perl or the like, I've taken your original code and added the relevant part to strip the troublesome / characters.

The initial // is the bash syntax for global replace (as we do have more than one troublesome /).

The subsequent / is to represent what we want to replace (/).

The final / precedes what we want to replace it with (nothing).

#!/bin/bash -f
for f in $(cat ./file.txt ); do
mkdir ${f////}
done
4
  • 1
    No more words. Genus !!
    – user88036
    Aug 7 '15 at 19:09
  • 1
    Does this work in shells other than bash? In particular, does it work in dash?
    – Kevin
    Aug 7 '15 at 20:42
  • 1
    No. You'd want to use something like "for f in $(cat ./file.txt | sed 's/\///g' ); do" for that. Or to strip the useless cat, "for f in $( sed 's/\///g' file.txt ); do"
    – steve
    Aug 7 '15 at 20:56
  • probably better to use a while loop to feed with the content of the file: while IFS= read -r line; do .... ; done < file. This way, you read it line by line.
    – fedorqui
    Aug 8 '15 at 13:51
2

And possible solution with awk:

awk -F"/" '{ print $1 $2 $3; }' file | xargs mkdir
1

This perl one line works for me.

cat data01.txt  |perl -ane 'chomp;s/\s+//g; s{\/}{}g; mkdir $_ if length($_);'
6
  • Thanks! Kindly could you please explain the code for me>
    – user88036
    Aug 7 '15 at 18:55
  • 1
    the '-an' tells perl to process the incoming text one line at a time. the text would also be parsed. the 'e' means the next part of the line is the perl script to run which follows in single quotes. the implicit variable in perl is $_ which is what chomp is processing. chomp removes the control characters at the end of the line. the s/\s+//g; just removes excess spaces. the s{/}{}g; remove the forward slashes. I used the {} instead of // for the substitution so I would not have to escape the forward slash.
    – DannyK
    Aug 7 '15 at 18:57
  • 1
    mkdir is a perl command that is similar to bash's mkdir. the implicit variable that perl is processing is the input to the mkdir command. i test if the $_ is of some size before we make the directory just to make sure I don't get a blank line.
    – DannyK
    Aug 7 '15 at 19:02
  • 1
    You don't need the cat here... Aug 7 '15 at 19:14
  • ...or the -a. The -n means iterate one line at a time for any files passed in (usually, the files are listed after the command, eg: perl -ne '...' file1.txt , without printing automatically. The -a is autosplit. What it does is it splits each line in the file (used with -n) into an array named @F (by default). eg: perl -ane 'print "$_\n" for @F' in.txt. In v5.20.0 and up, -a implies -n
    – stevieb
    Aug 7 '15 at 19:31
1

Here is a way with bash and sed

for var in $(cat data01.txt); do  dir=$(echo $var | sed -e 's/\///g;'); mkdir -vp $dir; done
6
  • ! Fantastic. I was on my way to ask for it ;))
    – user88036
    Aug 7 '15 at 18:58
  • I am receiving this error: "sed: -e expression #1, char 5: unknown option to `s'"
    – user88036
    Aug 7 '15 at 19:00
  • 1
    @MJA: Yes, it'll error , you should use for var in $(cat data01.txt); do dir=$(echo $var | sed -e 's/\///g;'); mkdir -vp $dir; done
    – neuron
    Aug 7 '15 at 19:02
  • 2
    Please also take a look at the ans given by @casey
    – neuron
    Aug 7 '15 at 19:03
  • 2
    And @don_crissti
    – neuron
    Aug 7 '15 at 19:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy