在我的日志目录中,我有600多个日志文件,其命名方案为:
abc.log.DDMMMYYYY
例如:
abc.log.01Nov2017
abc.log.02Nov2017
abc.log.10Dec2017
abc.log.21Jan2018
abc.log.22Jan2018
abc.log.23Jan2018
我正在寻找一种将所有这些文件重命名为...的方法
YYYY-MM-DD.abc.log
文件名中的月份名称必须转换为月份号。 (一月= 01,二月= 02 ...)
例如:
2017-11-01.abc.log
2017-11-02.abc.log
2017-12-10.abc.log
2018-01-21.abc.log
2018-01-22.abc.log
2018-01-23.abc.log
如何在bash中重命名所有这些文件?
答案 0 :(得分:2)
#!/bin/bash -e
# Create kludged associative array (for bash versions prior to 4 -- 4 has
# built-in associative arrays).
i=0
for Month in Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec; do
let i=i+1
# Pad with leading zero and then take last two characters.
Padded=0$i
eval Key$Month=${Padded: -2:2}
done
# Iterate on all files whose names match *.log.*.
for File in *.log.*; do
# Match to pattern with expected date format.
if [[ ! $File =~ ^(.*)\.log\.([0-3][0-9])([A-Z][a-z][a-z])([0-9]{4})$ ]]; then
echo "$File does not match pattern."
else
# Extract matched name and date.
Name=${BASH_REMATCH[1]}
Day=${BASH_REMATCH[2]}
InMonth=${BASH_REMATCH[3]}
Year=${BASH_REMATCH[4]}
# Convert month name abbreviation to month number.
# number %m, day number %d).
eval OutMonth=\$Key$InMonth
NewName="$Year-$OutMonth-$Day.$Name.log"
# Inform user.
echo "Will rename $File to $NewName."
# Rename.
mv "$File" "$NewName"
fi
done
当然,这是对语言环境敏感的。而且它期望四位数的日期,所以它将在10,000年终止。您可以添加各种错误检查。
答案 1 :(得分:1)
当您请求批处理文件解决方案时,以下是可能的解决方案:
@echo off
setlocal EnableDelayedExpansion
rem Set Month Numbers:
set "Jan=01"
set "Feb=02"
set "Mar=03"
set "Apr=04"
set "May=05"
set "Jun=06"
set "Jul=07"
set "Aug=08"
set "Sep=09"
set "Oct=10"
set "Nov=11"
set "Dec=12"
rem Main Loop to rename files:
for %%A IN (*.log.*) do (
for /f "delims=." %%B IN ("%%~xA") do (
set "extension=%%B"
call ren "%%A" "!extension:~5!-%%!extension:~2,-4!%%-!extension:~0,-7!.abc.log"
)
)
让我解释一下:
MMM
变量设置为请求的格式:MM
。%cd%
)中包含.log.
的所有文件。我们使用*
通配符进行此操作。
.
中设置扩展名(不带点(extension
)。%%A
)中找到的文件。为了更好地理解这些命令的工作方式,建议您打开一个cmd并键入以下命令:
set /?
rem /?
for /?
ren /?
一些有趣的参考资料供进一步阅读:
答案 2 :(得分:0)
如果gawk
可用,请尝试:
#!/bin/bash
for f in abc.log.*; do echo "$f"; done | awk 'BEGIN {
str="JanFebMarAprMayJunJulAugSepOctNovDec"
for (i=1; i<=12; i++) s2n[substr(str, i*3-2, 3)] = sprintf("%02d", i)
}
{if (match($0, "(.+)\\.([0-9]{2})([A-Z][a-z]{2})([0-9]{4})", a))
printf("%s%c%04d-%02d-%02d.%s%c", $0, 0, a[4], s2n[a[3]], a[2], a[1], 0)
}
' | xargs -0 -n 2 mv
s2n
将月份名称映射到月份号。awk
脚本输出成对的文件名,例如:abc.log.01Nov2017
,2017-11-01.abc.log
...文件名用空字符分隔。xargs
逐两读取传递的文件名,并在
他们。