在shell脚本中从文件名开始的年月日

我喜欢下面的文件名

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 

我想从文件名和创build目录中获得年,月,日

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

如何实现这一点,并分享给你的想法/脚本感激

如果文件名总是像你的例子,你可以使用像这样的东西:

 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 

这个子string的提取是可用的,不知道其他的shell。

使用Perl,它非常适合parsing文本。

 #!/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"; 

修改不同的文件格式的味道。 (正则expression式中的“括号”select模式元素)。

如果你在使用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" 

这是一个使用Bash的正则expression式匹配function的方法:

 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 

如果需要,模式可以变得更加健壮。