Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I hava file names like below

adn_DF9D_20140515_0001.log
adn_DF9D_20140515_0002.log
adn_DF9D_20140515_0003.log
adn_DF9D_20140515_0004.log
adn_DF9D_20140515_0005.log
adn_DF9D_20140515_0006.log
adn_DF9D_20140515_0007.log

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

3 Answers 3

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.

#!/usr/bin/perl

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 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 at 10:25

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

pattern='([[:digit:]]{4})([[:digit:]]{2})([[:digit:]]{2})'

for file in *.log
do
    [[ $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
done

The pattern can be made more robust if needed.

share|improve this answer

Your Answer

 
discard

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.