我有几个文件夹,如S1S、S2S、S3S,在每个文件夹中都有一个文件1。每个文件夹中的此文件1与
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 的空文件
有人能帮我找出我的错误吗?
这可能适用于您(GNU sed和并行(:
parallel sed 's/_{}.dat//' {}/file1 > {}/file2 ::: S*S
在file1
的每个目录S1S S2S S3S ...
中创建一个新文件file2
,并删除字符串_SnS.dat
(其中SnS表示当前目录(。
这里有几个问题。首先,正如konsolebox在评论中所说,sed -i
修改原始文件,而不是生成可以使用>
重定向的输出,因此需要删除该选项。
其次,变量不会在单引号字符串中展开,因此's/_${dir}.dat//g'
不使用dir
变量,它只是将整个变量视为文字字符串。
第三种可能还可以,但在脚本中使用cd
是危险的,因为如果由于某种原因失败,脚本的其余部分将在意外的地方运行,可能会产生非常糟糕的结果。通常最好使用显式路径,如sed ... "$dir/file1"
,而不是cd
到$dir
,然后使用sed ... file1
。
最后(这里可能也可以(,您几乎应该总是在变量引用周围加双引号,以避免对某些字符进行奇怪的解析。
以下是我如何重写脚本片段:
for dir in S*
do
sed "s/_${dir}.dat//g" "$dir/file1" > "$dir/file2"
done
p.s.shellcheck.net擅长发现shell脚本中的常见错误;它发现了我看到的四个问题中的三个(除了sed -i
问题之外的所有问题(。我建议您将脚本作为检查来运行。