如何用当前日期替换文件名中的日期部分

时间:2019-05-02 08:22:44

标签: linux bash shell unix

如何仅将日期部分替换为unix目录中存在的所有文件的当前日期。

文件夹路径: C:/shan

示例文件:

CN_Apria_837p_20180924.txt  
DN_Apria_837p_20150502.txt  
GN_Apria_837p_20160502.txt  
CH_Apria_837p_20170502.txt  
CU_Apria_837p_20180502.txt  
PN_Apria_837p_20140502.txt  
CN_Apria_837p_20101502.txt  

期望的结果应该是:

CN_Apria_837p_20190502.txt  
DN_Apria_837p_20190502.txt  
GN_Apria_837p_20190502.txt  
CH_Apria_837p_20190502.txt  
CU_Apria_837p_20190502.txt  
PN_Apria_837p_20190502.txt  
CN_Apria_837p_20190502.txt

编辑:

我对Unix销售脚本完全陌生。我在下面尝试过此方法,但是它不起作用。

#!/bin/bash

for i in ls $1 | grep -E '[0-9]{4}-[0-9]{2}-[0-9]{2}'
do
  x=echo $i | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}'
  y=echo $i | sed "s/$x/$(date +%F)/g"
  mv $1/$i $1/$y 2>/dev/null #incase if old date is same as current date
done

3 个答案:

答案 0 :(得分:0)

下面应该这样做

for f in $(find /path/to/files -name "*_*_*_*.txt")
do 
  newname=$(echo "$f" | sed -r "s/[12][0-9]{3}[01][0-9][0-3][0-9]/$(date '+%Y%m%d')/g")   
  mv "$f" "$newname" 
done

答案 1 :(得分:0)

我会在这里使用正则表达式。在bash手册页中:

  

另一个可用的二进制运算符=〜可用,具有相同的     优先级为==和!=。使用时,右边的字符串     的运算符被认为是扩展的正则表达式,并且     相应地进行匹配(如regex(3)中所示)。如果返回值是0,则返回值为0。     字符串匹配模式,否则为1。 ....子字符串
    与正则内带括号的子表达式匹配     表达式保存在数组变量BASH_REMATCH中。 ...     具有索引n的BASH_REMATCH的元素是     匹配第n个带括号的子表达式的字符串。

因此,假设变量x拥有文件之一的名称 有问题的代码

if [[ $x =~ ^(.*_)[0-9]+([.]txt$) ]]
then
  mv "$x" "$BASH_REMATCH[1]$(date +%Y%m%d)$BASH_REMATCH[2]"
fi

首先大致测试文件是否确实遵循所需的命名方案,然后相应地修改名称。

当然,在实践中,您将定制正则表达式以更好地匹配您的应用程序。只有您知道允许对文件名进行哪些更改。

答案 2 :(得分:0)

尝试使用此Shellcheck干净的代码:

#! /bin/bash -p

readonly dir=$1

shopt -s nullglob  # Make glob patterns that match nothing expand to nothing

readonly dateglob='20[0-9][0-9][0-9][0-9][0-9][0-9]'
currdate=$(date '+%Y%m%d')

# shellcheck disable=SC2231
for path in "$dir"/*_${dateglob}.* ; do
    name=${path##*/}
    newname=${name/_${dateglob}./_${currdate}.}
    if [[ $newname != "$name" ]] ; then
        newpath="$dir/$newname"
        printf "%q -> %q\\n" "$path" "$newpath"
        mv -i -- "$path" "$newpath"
    fi
done
  • shopt -s nullglob如果没有任何匹配for path in ...中的glob模式的代码,则停止尝试处理垃圾路径的代码。
  • 分配给dateglob的模式假定您不必处理2000年之前(或2099年之后!)的日期。如果该假设无效,请更改它。
  • # shellcheck ...行旨在防止Shellcheck关于使用${dateglob}而不带引号的警告。在这种情况下,引号是错误的,因为它们会阻止全局模式扩展。
  • 用于匹配文件名(*_${dateglob}.*)的模式将比给出的示例(例如A_20180313.tar.gz)匹配更多形式的文件名。您可能要更改它。
  • 有关使用的Bash字符串操纵机制(${path##...}${name/...})的信息,请参见Removing part of a string (BashFAQ/100 (How do I do string manipulation in bash?))
  • 我添加了printf,以输出要移动的内容的详细信息。
  • -i的{​​{1}}选项提示您确认是否覆盖文件。事实证明,这是示例文件的问题,因为mvCN_Apria_837p_20180924.txt除日期外都是相同的,因此代码尝试将它们重命名为同一内容。
  • 如果名称中带有日期的任何文件的名称均以“。”开头,则代码将不会对其进行处理。如果有问题,请在循环之前的某处添加行CN_Apria_837p_20101502.txt