目前,多个文件位于名称为
的文件夹中 yyyymmdd_TCT_XPL_PLA_Attribution.tab
示例:
20160301_TCT_XPL_PLA_Attribution.tab
我想用命名约定重命名所有文件:
XPL_PNL_Attribution_2016-03-01
必须重命名文件以符合一般命名约定(XPL_PNL_Attribution_yyyy-mm-dd
):
1)第一个粒子应该是“类”,这意味着文件名前缀,直到第一个下划线,需要在文件名中添加前缀(XPL_PNL Attribution_
)
2)文件名的日期部分应为yyyy-mm-dd
,而不是yyyymmdd
,就像它在这里一样,需要添加破折号
答案 0 :(得分:1)
您可以尝试使用Bash参数替换:
for f in *.tab; do
mv "${f}" XPL_PNL_Attribution_"${f:0:4}"-"${f:4:2}"-"${f:6:2}";
done
答案 1 :(得分:1)
您可以通过将文件名拆分为以下划线分隔的字段来完成此操作。
$ f=20160301_TCT_XPL_PLA_Attribution.tab
$ IFS=_
$ a=( ${f%.*} )
$ declare -p a
declare -a a='([0]="20160301" [1]="TCT" [2]="XPL" [3]="PLA" [4]="Attribution")'
$ new="$(printf '%s_%s_%s_%s' "${a[2]}" "${a[3]}" "${a[4]}" "${a[0]:0:4}-${a[0]:4:2}-${a[0]:6:2}")"
脚本处理文件目录需要for循环:
IFS=_
for f in *.tab; do
a=( ${f%.*} )
new="$(printf '%s_%s_%s_%s' "${a[2]}" "${a[3]}" "${a[4]}" "${a[0]:0:4}-${a[0]:4:2}-${a[0]:6:2}")"
mv -v "$f" "$new"
done
或者,您可以使用正则表达式收集文件名部分:
$ [[ $f =~ ^([^_]+)_([^_]+)_([^_]+)_([^_]+)_([^.]+) ]]
$ declare -p BASH_REMATCH
declare -ar BASH_REMATCH='([0]="20160301_TCT_XPL_PLA_Attribution" [1]="20160301" [2]="TCT" [3]="XPL" [4]="PLA" [5]="Attribution")'
编写脚本可以采用相同的方式,只需要引用$BASH_REMATCH[]
数组而不是$a[]
,您就不需要使用$IFS
。
for f in *.tab; do
[[ $f =~ ^([^_]+)_([^_]+)_([^_]+)_([^_]+)_([^.]+) ]]
new="${BASH_REMATCH[3]}_${BASH_REMATCH[4]}_${BASH_REMATCH[5]}_${BASH_REMATCH[0]:0:4}-${BASH_REMATCH[0]:4:2}-${BASH_REMATCH[0]:6:2}"
mv -v "$f" "$new"
done
答案 2 :(得分:0)
echo "20160301_TCT_XPL_PLA_Attribution.tab" | sed -e "s/^\(....\)\(..\)\(..\)_....\([^.]*\).\(.*\)$/\4_\1-\2-\3.\5/g" | sed -e "s/_PLA_/_PNL_/g"
或
echo "20160301_TCT_XPL_PLA_Attribution.tab" | sed -e "s/^\([0-9][0-9][0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]\).*_\([^.]*\).\(.*\)$/XPL_PNL_\4_\1-\2-\3.\5/g"
答案 3 :(得分:0)
丑陋,不活泼,未经测试,但对输入文件名灵活,假设始终丢弃TCT字段。
# 20160301_TCT_XPL_PLA_Attribution.tab # XPL_PNL_Attribution_2016-03-01 # 1 2 3 4 file_out="$( echo "$file_in" | sed -r -e 's/^\([12][0-9]{3}\)\([0-9][0-9]\)\([0-9][0-9]\)_[A-Za-z]+_\(.*\)\.tab/($4)_$1-$2-$3/' )"; mv "$file_in" "$file_out"