如何仅将日期部分替换为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
答案 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
)匹配更多形式的文件名。您可能要更改它。${path##...}
,${name/...}
)的信息,请参见Removing part of a string (BashFAQ/100 (How do I do string manipulation in bash?))。printf
,以输出要移动的内容的详细信息。-i
的{{1}}选项提示您确认是否覆盖文件。事实证明,这是示例文件的问题,因为mv
和CN_Apria_837p_20180924.txt
除日期外都是相同的,因此代码尝试将它们重命名为同一内容。CN_Apria_837p_20101502.txt
。