在 Solaris 上,我有一个脚本可以成功做到这一点:
USER,REPORT_NAME,DD:MM:HH24.pdf -> USER,REPORT_NAME,DD_MM_HH24.pdf
一行是这样的:
for f in *:*; do mv "$f" $(echo "$f" | tr ':' '_'); done
但现在,我必须撤消它,并且还按创建日期进行筛选(例如,最近 15 天生成的报告)。因此,对于过去 15 天生成的报告,我必须进行以下重命名:
USER,REPORT_NAME,DD_MM_HH24.pdf -> USER,REPORT_NAME,DD:MM:HH24.pdf
如何只替换_
该部分中的字符 ( ) DD_MM_HH24
,而不修改REPORT_NAME
文件名中的部分?并按修改日期过滤报告?
可能的解决方案: 我想出了一个不太优雅的解决方案。执行两次命令,以每次替换最后一次出现的“_”:
$ echo "ADMIN,IN_CO_GE,17-09-2015,11_17_06.pdf" | sed 's/\(.*\)_/\1:/'
ADMIN,IN_CO_GE,17-09-2015,11_17:06.pdf
$ echo "ADMIN,IN_CO_GE,17-09-2015,11_17:06.pdf" | sed 's/\(.*\)_/\1:/'
ADMIN,IN_CO_GE,17-09-2015,11:17:06.pdf
最终解决方案 感谢混乱,这是我的问题的最终解决方案:
for f in *; do mv "$f" $(echo "$f" | nawk -F, '{OFS=",";gsub(/_/, ":", $NF)}1'); done
答案1
您可以awk
为此使用:
for f in *; do
mv "$f" $(echo "$f" | awk -F, '{OFS=",";gsub(/_/, ":", $NF)}1')
done
这将替换_
为:
,但仅在最后一个由 分隔的字段中,
:
-F,
将awk
s 分隔符设置为,
OFS=",";
将输出字段分隔符设置为,
gsub(...)
将最后一个字段中的全部替换_
为:
$NF
- 最后的条件
1
是真条件,awk
打印整行。
编辑:在 Solaris 上,您必须使用nawk
(这是 Solaris 系统上唯一awk
具有该gsub()
功能的)而不是旧的awk
:
for f in *; do
mv "$f" $(echo "$f" | nawk -F, '{OFS=",";gsub(/_/, ":", $NF)}1')
done
编辑2:对于 mtime 晚于 30 天的文件:
for f in *; do
[ $(stat -c %Y "") -gt $(expr $(date +%s) - 30 \* 86400) ] && \
mv "$f" $(echo "$f" | nawk -F, '{OFS=",";gsub(/_/, ":", $NF)}1')
done