我有一些时间和日期错误的文件,但是文件名包含正确的时间和日期,因此我尝试编写一个脚本使用touch命令来解决此问题。
文件名示例: 071212_090537.jpg
我希望将其转换为以下格式: 1712120905.37
请注意,年份在文件名中被列为07,即使它是17,所以我希望将第一个0更改为1。
如何使用awk或sed执行此操作?
我对awk和sed还是很陌生,这是一种一般的编程方法。曾经尝试寻找解决方案和说明,但没有设法找出解决方法。
有人可以帮助我吗?
谢谢。 :)
答案 0 :(得分:0)
以您的示例为例:
std::unique_ptr<Widget[], WidgetDeleter>
将输出:
awk -F'[_.]' '{$0=$1$2;sub(/^./,"1");sub(/..$/,".&")}1'<<<"071212_090537.jpg"
如果要删除文件,可以让awk生成1712120905.37
命令,然后将输出通过管道传递到mv origin new
,例如:(内联注释)
|sh
答案 1 :(得分:0)
为此完全不需要调用awk或sed,您可以在您的shell中进行操作。例如用bash:
$ f='071212_090537.jpg'
$ [[ $f =~ ^.(.*)_(.*)(..)\.[^.]+$ ]]
$ echo "1${BASH_REMATCH[1]}${BASH_REMATCH[2]}.${BASH_REMATCH[3]}"
1712120905.37
这可能是您要尝试执行的操作:
for old in *.jpg; do
[[ $old =~ ^.(.*)_(.*)(..)\.[^.]+$ ]] || { printf 'Warning, unexpected old file name format "%s"\n' "$old" >&2; continue; }
new="1${BASH_REMATCH[1]}${BASH_REMATCH[2]}.${BASH_REMATCH[3]}"
[[ -f "$new" ]] && { printf 'Warning, new file name "%s" generated from "%s" already exists, skipping.\n' "$new" "$old" >&2; continue; }
mv -- "$old" "$new"
done
您需要对已经存在的新测试进行测试,因为旧的071212_090537.jpg
或171212_090537.jpg
(或其他各种值)会创建相同的新的1712120905.37
答案 2 :(得分:0)
我认为sed确实是最简单的解决方案:
您可以这样做:
▶ for f in *.jpg ; do
new_f=$(sed -E 's/([0-9]{6})_([0-9]{4})([0-9]{2})\.jpg/\1\2.\3.jpg/' <<< $f)
mv $f $new_f
done
有关更多信息:
您可能需要阅读有关正则表达式的入门教程。
请注意,sed的-E
选项允许使用扩展的正则表达式,从而使此处的表达式更易读和方便。
使用<<<
是一种称为“ here-string”的Bashism。如果您使用的外壳程序不支持该外壳程序,则可以将A <<< $b
改写为echo $b | A
。
测试:
▶ touch 071212_090538.jpg 071212_090539.jpg
▶ ls -1 *.jpg
071212_090538.jpg
071212_090539.jpg
▶ for f in *.jpg ; do
new_f=$(sed -E 's/([0-9]{6})_([0-9]{4})([0-9]{2})\.jpg/\1\2.\3.jpg/' <<< $f)
mv $f $new_f
done
▶ ls -1
0712120905.38.jpg
0712120905.39.jpg