从多个文件中提取前缀,并通过添加后缀

时间:2016-03-17 12:56:44

标签: bash shell

目前,多个文件位于名称为

的文件夹中

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,就像它在这里一样,需要添加破折号

4 个答案:

答案 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"