我需要重命名多个文件的部分内容,同时保留文件名中的 IP 地址。
例如,
Abc_192.168.1.164_001.txt
Abc_10.11.76.112_001.txt
Abc_54.78.1.1_002.txt
我需要保留“Abc_”部分以及 IP 地址。之后的所有内容都将替换为日期和时间戳。我会将当前日期和时间戳添加为“_yymmdd-yymmdd-hhmmss”,并且我们会将扩展名更改为“.csv”。这将在 Linux 上运行。
答案1
这是一个简单的 shell 循环,用于(小心地)重命名文件,正如我认为您所要求的那样:
d=$(date +%y%m%d-%y%m%d-%H%M%S)
for f in Abc_*.*.*.*_*.txt
do
new=${f%_*}_${d}.csv
[ ! -f "$new" ] && mv "$f" "$new"
done
它首先以您编写的格式将时间戳捕获到名为 的变量中d
。然后,它循环使用简单的 glob 格式,以拾取名称以“Abc_”开头的所有文件,然后在三个句点之间包含任何内容,后跟任何内容,然后后跟下划线和任何内容,最后以“.txt”结尾。
它通过去掉最后一个下划线之后的所有内容(包括 和 )来计算新文件名,然后附加时间戳 ( ${d}
) 和新的“.csv”扩展名。
如果新文件名是不是存在,那么它将重命名该文件。[ ! -f "$new" ] &&
如果您不关心破坏现有文件,请删除该部分。
如果您想在实际执行之前看看它会做什么,请在echo
之前添加一个。mv
当我运行它时,我看到:
$ touch Abc_10.11.76.112_001.txt Abc_192.168.1.164_001.txt Abc_54.78.1.1_002.txt
$ d=$(date +%y%m%d-%y%m%d-%H%M%S)
$ for f in Abc_*.*.*.*_*.txt; do new=${f%_*}_${d}.csv; [ ! -f "$new" ] && mv "$f" "$new"; done
$ ls -1
Abc_10.11.76.112_160913-160913-140649.csv
Abc_192.168.1.164_160913-160913-140649.csv
Abc_54.78.1.1_160913-160913-140649.csv
答案2
如果通过日期和时间戳,你的意思是文件的修改时间,zsh
你可以这样做:
zmodload zsh/stat
autoload zmv
zmv -n '(*_*_)*(.txt)' '$1$(zstat -F %FT%T%z +mtime -- $f)$2'
(删除-n
以实际进行重命名)
请注意,对于那些.txt
符号链接的文件,时间戳基于符号链接目标的修改时间,而不是符号链接本身的修改时间。添加-L
选项以zstat
使用符号链接本身的修改时间。
%FT%T%z
给出明确的本地时间戳,例如2016-09-13T17:32:17+0100
.您可以使用标准格式来适应您的需要strftime()
(与 相同date +<format>
)。但请注意,zsh
不zstat
支持亚秒精度(对于以亚秒精度存储修改时间的文件系统)。
如果在 GNU 系统上,您可以使用 GNUdate -r
而不是zstat
获取这些纳秒:
$ zmv -n '(*_*_)*(.txt)' '$1$(date -r $f +%FT%T.%N%z)$2'
mv -- Abc_192.168.1.164_001.txt Abc_192.168.1.164_2016-09-13T17:32:17.368805094+0100.txt
就像 for 一样zstat
,这需要修改时间目标符号链接的,而不是符号链接本身的。date
没有使用符号链接的 mtime 的选项,但您可以使用 GNUfind
代替。