我有一组3个文件,用日期编码:
abc1_bbb_yyy_2_8_15.csv
abd1_bba_yzy_11_8_16.csv
aby1_qba_yay_11_21_16.csv
最后三个数字代表日期:
2815
11816
112116
我需要使用单个正则表达式过滤器提取文件名中与日期对应的数字,该过滤器也会将结果转换为MMDDYY格式:
020815
110816
112116
感谢您的帮助!
答案 0 :(得分:3)
awk -F'[_.]' '{printf "%02d%02d%02d\n",$(NF-3),$(NF-2),$(NF-1)}'
答案 1 :(得分:1)
这似乎是一个有趣的问题,尝试用sed解决。
我更喜欢TessellatingHeckler的perl方法。 : - )
编辑:睡过了,我更喜欢jthill的awk方法。
技术上有趣的尝试用sed解决但不是我想长期生活的东西。
示例数据文件......
from datetime import datetime,timedelta
current_date=datetime.now()
currQuarter = (current_date.month - 1) / 3 + 1
dtFirstDay = datetime(current_date.year, 3 * currQuarter - 2, 1)
dtLastDay = datetime(current_date.year, 3 * currQuarter + 1, 1) + timedelta(days=-1)
请注意,sed -r启用了常规的epxression扩展。
$ cat foo.dat
abc1_bbb_yyy_2_8_15.csv
abd1_bba_yzy_11_8_16.csv
aby1_qba_yay_11_21_16.csv
$
通常我不是很啰嗦。 : - )
但我认为这些评论会使目的更明确。
$ sed -rf foo.sed < foo.dat
020815
110816
112116
$
答案 2 :(得分:1)
正如其他人所指出的那样,sed
并不是这项工作最优雅的工具。使用perl,
fn='abc1_bbb_yyy_2_8_15.csv abd1_bba_yzy_11_8_16.csv aby1_qba_yay_11_21_16.csv'
for x in $fn; do
echo $x | perl -n -e 'printf("%02d%02d%02d\n",/(\d+)_(\d+)_(\d+)\./)'
done
如果您真的被限制使用sed
,那么这就是一种方法。第一个正则表达式以前缀为下划线的数字为前缀。第二个查找数字字符串,后跟下划线或点,并删除每次出现的最后2位数字。最后一个提取6个数字的最后一个字符串,后面跟着任何东西,但后跟非数字。
for x in $fn; do
echo $x | sed -e 's/_\([0-9]\)/_0\1/g' \
-e 's/[0-9]*\([0-9]\{2\}\)[_.]/\1/g' \
-e 's/.*\([0-9]\{6\}\)[^0-9]*$/\1/'
done
结果:
$ for x in $fn; do
> echo $x | sed -e 's/_\([0-9]\)/_0\1/g' \
> -e 's/[0-9]*\([0-9]\{2\}\)[_.]/\1/g' \
> -e 's/.*\([0-9]\{6\}\)[^0-9]*$/\1/'
> done
020815
110816
112116
答案 3 :(得分:0)
试试这个:
REST = cat#无论你的其他管道是什么......
( cat <<EOF
abc1_bbb_yyy_2_8_15.csv
abd1_bba_yzy_11_8_16.csv
aby1_qba_yay_11_21_16.csv
EOF
)\
| cut -d_ -f4-6 \
| cut -d. -f1 \
| sed -e 's/\([0-9][0-9]*\)/0\1/g' \
-e 's/0\([0-9][0-9]\)/\1/g' \
-e 's/_//g' \
| $REST
答案 4 :(得分:-2)
将文件名放入t.txt
abc1_bbb_yyy_2_8_15.csv
abd1_bba_yzy_11_8_16.csv
aby1_qba_yay_11_21_16.csv
然后
$ cat t.txt | perl -p -e 's/(?<=_)(\d)(?=_)/0\1/g' | perl -p -e 's/.*(\d\d)_(\d\d)_(\d\d)\.csv/\1\2\3/'
020815
110816
112116
这不完全是sed / awk / grep,因为sed不能做外观,我现在不想要AWK,但它是正则表达式,而且是* nixy。
[编辑:好的,不喜欢Perl的downvoters,我的方法是先用0加前缀一位数,然后提取双位数对。 sed在没有外观或非捕获组的情况下做得很难,但这里有一个sed的答案,使用@ jgreve的想法,先把楔子放在一边。这还包括YYYYMMDD格式的输出,假设所有年份都是20:
# #wedge #single n to 0n #extract __dd__mm__yy to 20yymmdd
cat t.txt | sed -e 's/_/__/g' -e 's/_\([0-9]\)_/_0\1_/g' -e 's/.*__\([0-9][0-9]\)__\([0-9][0-9]\)__\([0-9][0-9]\)\.csv/20\3\2\1/'