【问题标题】:sed command to change names for few files in different directories at oncesed 命令一次更改不同目录中的几个文件的名称
【发布时间】:2021-08-27 23:36:43
【问题描述】:

我有几个文件夹,如 S1S、S2S、S3S ...,在每个文件夹中都有一个 file1。 这个file1在每个文件夹中都是一致的

1990.A.BHT_S1S.dat
1994.I.BHT_S1S.dat
1995.K.BHT_S1S.dat
同样S1S扩展名根据文件夹变化。

我正在尝试使用此命令将所有文件夹的这些名称更改为 1990.A.BHT 类型

for dir in S*
do
cd $dir
sed -i 's/_${dir}\.dat//g' file1 > file2
cd ../
done

但我得到一个文件 2 的空文件

有人可以帮我找出我的错误吗?

【问题讨论】:

  • 您因为-i而修改了您的file1文件。
  • 你好@konsolebox 对不起,你是什么意思?我也试过sed 's/_${dir}\.dat//' file1 > file2
  • -i 选项允许就地修改目标文件并且不向标准输出发送输出。这就是为什么你得到空的file2 文件,并且你的file1 文件已经被修改(可能)。更详细地说,1990.A.BHT_S1S.dat1994.I.BHT_S1S.dat1995.K.BHT_S1S.dat 的字符串(很可能)已经在 file1 中进行了更改。我不确定您将如何恢复这些更改,或者您是否想保留它们。也许你有一个我不知道的备份。由你决定。我刚刚告诉你-i的效果。
  • 谢谢@konsolebox 我明白了。使用 -i 后,我的 file1 没有被修改。但我有备份以防万一。

标签: bash ubuntu sed


【解决方案1】:

这可能对你有用(GNU sed 和并行):

parallel sed 's/_{}\.dat//' {}/file1 \> {}/file2 ::: S*S

file1 的每个目录S1S S2S S3S ... 中创建一个新文件file2,删除字符串_SnS.dat(其中SnS 表示当前目录)。

【讨论】:

  • 我收到了这个错误parallel: command not found
  • @Monika 你需要安装它。
  • 哦,我明白了。谢谢
【解决方案2】:

这里有几个问题。首先,正如 konsolebox 在评论中所说,sed -i 会修改原始文件,而不是生成可以使用> 重定向的输出,因此您需要删除该选项。

其次,变量不会在单引号字符串中展开,因此's/_${dir}\.dat//g' 不使用dir 变量,它只是将整个内容视为文字字符串。

第三个可能没问题,但是在脚本中使用cd 是危险的,因为如果由于某种原因失败,脚本的其余部分将在意想不到的地方运行,使用possibly very bad results。通常最好使用显式路径,例如 sed ... "$dir/file1" 而不是 cding 到 $dir 然后使用 sed ... file1

最后(在这里也可能没问题)是你应该几乎总是在变量引用周围加上双引号,以避免对某些字符进行奇怪的解析。

下面是我重写脚本 sn-p 的方法:

for dir in S*
do
    sed "s/_${dir}\.dat//g" "$dir/file1" > "$dir/file2"
done

附言shellcheck.net 擅长发现 shell 脚本中的常见错误;它发现了我看到的四个问题中的三个(除了sed -i 问题之外的所有问题)。我建议通过它运行您的脚本作为检查。

【讨论】:

  • 太棒了。谢谢@Gordon
猜你喜欢
  • 2011-05-23
  • 1970-01-01
  • 1970-01-01
  • 2018-01-19
  • 2018-10-07
  • 2023-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多