我有一堆包含许多空白行的文件,并希望删除任何重复的空白行,以便更轻松地阅读文件。我写了以下脚本:
#!/bin/bash
for file in * ; do cat "$file" | sed 's/^ \+//' | cat -s > "$file" ; done
然而,这有非常不可靠的结果,大多数文件变得完全空,只有少数文件具有预期的结果。更重要的是,每次重试时,工作的文件似乎都会随机变化,因为每次运行都会正确编辑不同的文件。发生了什么事?
注意:这更像是一个理论问题,因为我意识到我可以使用类似的解决方法:
#!/bin/bash
for file in * ; do
cat "$file" | sed 's/^ \+//' | cat -s > "$file"-tmp
rm "$file"
mv "$file"-tmp "$file"
done
但这似乎不必要地令人费解。那么为什么“直接”方法如此不可靠?
答案 0 :(得分:2)
出现不可预测性是因为管道中的两个阶段cat "$file"
和cat -s > "$file"
之间存在竞争条件。
第一个尝试打开文件并从中读取,而另一个尝试清空文件。
如果你有GNU sed,你可以简单地做sed -i 'expression' *
答案 1 :(得分:1)
如果您同时写入文件,则无法从文件中读取。 >
重定向首先清除文件,因此无需再阅读。
您可以使用sed -i -e '/^$/d'
删除空行(如果您的sed支持-i
),这会在引擎盖下创建临时文件。