如果第一个字段值大于 400,则删除每个文本文件中的行

如果第一个字段值大于 400,则删除每个文本文件中的行

我有大量的txt文件。每个txt文件的格式与此类似

200 0.2 0.1 0.5 0.4
500 0.4 0.9 0.9 0.1

我试图删除每个 txt 文件中第一个字段值大于 400 的每一行。因此上面的文件现在应该只包含以下内容:

200 0.2 0.1 0.5 0.4

代码

for file in *.txt; do 
        echo "$(awk '{ if ($1 < 401) print }' *.txt)" > tmp && mv tmp *.txt 
done 
rm -f tmp 

但这不起作用,因为它将所有文件移动到下一个文本文件。

答案1

如果您使用 GNU awk(如果您使用 Linux,则几乎肯定是这样),您可以使用 GNU awk 的就地编辑库,甚至不需要 shellfor循环或任何临时文件来完成此操作。

 awk -i inplace '$1 < 401' ./*.txt

这将从每个文本文件中删除字段 1 > 400 的所有行。它的工作原理是首先加载 GNU awk 的inplace库,然后仅输出$1 < 401计算结果为 true 的行。

如果您希望 awk 在更改每个原始文件(例如带有 .bak 文件扩展名)之前对其进行备份,您可以使用 awk 的 INPLACE_SUFFIX 变量:

 awk -i inplace -v INPLACE_SUFFIX=.bak '$1 < 401' ./*.txt

注意:与其他具有就地编辑选项的程序(例如sedperl)不同, GNU awk 的选项是...ie 的缩写,即包含下一个参数中指定的 gawk 库。这个库(称为“inplace”)提供了就地编辑功能。-i-i--include

答案2

file您需要在循环中引用;也没有必要使用echo

for file in *.txt; do 
        awk '{ if ($1 < 401) print }' < "$file" > tmp && mv -- tmp "$file"
done 
rm -f tmp

AWK 代码也可以简化:

for file in *.txt; do 
        awk '$1 < 401' < "$file" > tmp && mv -- tmp "$file"
done 
rm -f tmp

为了完全满足您的要求,应该更改测试:

for file in *.txt; do 
        awk '!($1 > 400)' < "$file" > tmp && mv -- tmp "$file"
done 
rm -f tmp

答案3

您可以像这样更改代码来完成这项工作:

for file in *.txt; do 
        awk '{ if ($1 < 401) print }' < "$file" > tmp && mv -- tmp "$file" 
done 
rm -f tmp 

但是在覆盖原始文件时要小心,最好在不同的目录(类似的目录)中创建修改后的文件:mv tmp modified/$file并且不要忘记在将文件复制到该目录之前创建该目录。

如果您将逻辑定义为“大于 400”,您if应该是:($1 <= 400数字可以是 400.1)

相关内容