使用sed或awk更改字符串

时间:2019-04-27 18:34:37

标签: awk sed

我有一些时间和日期错误的文件,但是文件名包含正确的时间和日期,因此我尝试编写一个脚本使用touch命令来解决此问题。

文件名示例: 071212_090537.jpg

我希望将其转换为以下格式: 1712120905.37

请注意,年份在文件名中被列为07,即使它是17,所以我希望将第一个0更改为1。

如何使用awk或sed执行此操作?

我对awk和sed还是很陌生,这是一种一般的编程方法。曾经尝试寻找解决方案和说明,但没有设法找出解决方法。

有人可以帮助我吗?

谢谢。 :)

3 个答案:

答案 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.jpg171212_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