【问题标题】:Extract prefix from multiple files and rename by adding as suffix从多个文件中提取前缀并通过添加为后缀重命名
【发布时间】:2016-03-17 12:56:44
【问题描述】:

当前多个文件在一个文件夹中,名称为:

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,需要添加破折号

【问题讨论】:

  • 在您的“想要重命名”示例中,我看不到“PNL”的来源。

标签: bash shell


【解决方案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

【讨论】:

  • 是否有理由在全局范围内使用设置 IFS 而不是 IFS=_ read ymd _ rest?这也将拆分限制为所需的字段?
  • @EtanReisner - .. 只是我的懒惰。是的,read 是一个很好的建议。与往常一样,tmtowtdi。
【解决方案2】:

你可以试试这个,使用 Bash 参数替换:

for f in *.tab; do
    mv "${f}" XPL_PNL_Attribution_"${f:0:4}"-"${f:4:2}"-"${f:6:2}";
done

【讨论】:

    【解决方案3】:
    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"
    

    【讨论】:

      【解决方案4】:

      丑陋,未经调试,未经测试,但传入文件名灵活,假设 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"

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-02
        • 2018-11-10
        • 2014-01-19
        • 1970-01-01
        • 1970-01-01
        • 2011-06-14
        相关资源
        最近更新 更多