Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I hava file names like below


i want get the year, Month, day from file name and create directories

Ex: [[ ! -d "$BASE_DIR/$year/$month/$day" ]] && mkdir -p "$BASE_DIR/$year/$month/$day";

How to achieve this and share the ideas/ script appreciate to you

share|improve this question

If the file name is always like in your example you can use something like:

for x in *.log; do year=${x:9:4}; month=${x:13:2}; day=${x:15:2}; [[ ! -d "$year/$month/$day" ]] && mkdir -p "$year/$month/$day"; done

This substring extraction is available in bash, not sure about other shells.

share|improve this answer

Use Perl, it's excellent for parsing text.


use strict;
use warnings;

my $filename = "adn_DF9D_20140515_0001.log";

my ( $year, $month, $day ) = ( $filename =~ m/adn_DF9D_(\d{4})(\d{2})(\d{2})/ );

print "$year $month $day\n";

Amend for differing file formats to taste. (The 'brackets' in the regular expression select pattern elements).

If you're dead set on using shell:

DATE=`echo $FILENAME | cut -d_ -f 3`
YEAR=`echo $DATE | cut -c1-4`
MONTH=`echo $DATE | cut -c5-6`
DAY=`echo $DATE | cut -c7-8`
mkdir -p "$YEAR/$MONTH/$DAY"
share|improve this answer
is it possible to implement same to shell script. I am trying yo create directories using aboves script it' giving the error "Use of uninitialized value in mkdir at ./main line 10." i am just added one line of creating directories "[[ ! -d "$year/$month/$day" ]] && mkdir -p "$year/$month/$day";" suggest to me – user3319390 Jun 10 '14 at 10:20
Yes, it is. But shell has limitations, and they start to get messy. You can inline the perl if you're so inclined. Otherwise, I'd be suggesting that you think in terms of 'cut'. Example added to answer, because formatting. – Sobrique Jun 10 '14 at 10:25

Here's a method using Bash's regex matching feature:'


for file in *.log
    [[ $file =~ $pattern ]]
    read -r _ year month day <<< "${BASH_REMATCH[@]}"
    mkdir -p "$BASE_DIR/$year/$month/$day" # no need to test for existence when you use -p with mkdir

The pattern can be made more robust if needed.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.