使用sed在bash脚本中进行就地重命名

时间:2014-04-23 03:40:11

标签: macos bash shell sed scripting

我在OSX上有一个文件夹,其中有从在线DVR下载的电视节目。我想列出一些程序并将其格式化以匹配另一个列表进行比较。

当我在shell中运行以下命令时,一切正常,我得到了我想要的列表。

ls *.mp4 > loaded_shows.txt
sed -i$0 's/\(.*\)_/\1\ /' loaded_shows.txt
sed -i$0 's/\(.*\)_/\1\ /' loaded_shows.txt
sed -i$0 's/\(.*\)_/\1\ /' loaded_shows.txt
cat loaded_shows.txt

当我将相同的命令放入bash脚本时,sed会为每个就地替换提供以下错误消息,即使脚本与文件位于同一目录中。

sed:rename():没有这样的文件或目录

为了完整起见,这里是bash脚本:

#!/bin/bash
ls *.mp4 > loaded_shows.txt
sed -i$0 's/\(.*\)_/\1\ /' loaded_shows.txt # replace last _ with space
sed -i$0 's/\(.*\)_/\1\ /' loaded_shows.txt # again replace last _ with space
sed -i$0 's/\(.*\)_/\1\ /' loaded_shows.txt # remove the file extension
cat loaded_shows.txt

示例输入文件名:

666_Park_Avenue_2014-04-22_23.35.mp4
Americans_2014-04-20_22.45.mp4
Scandal_2014-04-20_21.00.mp4
The_Voice_of_USA_2014-04-22_19.30.mp4

如何让sed在bash脚本中工作?

1 个答案:

答案 0 :(得分:0)

您已经使用sed的-i选项注意到了错误。找到它做得很好。 :)

如果脚本中的注释表明您要实现的目标,我实际上会重构脚本以在管道中使用sed,只需一次,看起来像这样:

#!/bin/bash

for f in *.mp4; do
  echo "$f" | sed 's/_\([^_]*\)_\([^_]*\).mp4$/ \1 \2/'
done > loaded_shows.txt

运行sed更少的时间更经济,只打开/关闭文本文件一次更经济。因为,你知道,浪费的毫秒是毫秒的损失。

我应该在这里指出for循环。通常,当您在shell脚本中运行文件列表时,您希望使用for而不是解析ls的输出。 Parsing ls是shell脚本世界中众所周知的问题,最好不要让自己有这样的坏习惯,即使在受控环境中的小脚本中也是如此。