sed 命令一次更改不同目录中的几个文件的名称

Posted

技术标签:

【中文标题】sed 命令一次更改不同目录中的几个文件的名称【英文标题】:sed command to change names for few files in different directories at once 【发布时间】: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 没有被修改。但我有备份以防万一。 【参考方案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

以上是关于sed 命令一次更改不同目录中的几个文件的名称的主要内容,如果未能解决你的问题,请参考以下文章

linux常用的几个命令

CISCO处理本地文件系统的几个命令

如何告诉 Git 它是同一个目录,只是名称不同

处理/etc/fstab路径,使用sed命令取出其目录名和基名

测试工作中经常用到的几个Linux命令(第一弹)

在 Databricks 文件系统中更改文件夹名称