AWK:替换并在输入文件中写入列值

时间:2012-03-14 16:26:59

标签: awk

我正在尝试替换输入文件的$ 3列值,如果$ 3是>我试过了:

awk 'BEGIN {FS="\t"} {if($3 > 100) $3=$3/100;print}' test.stat

这会输出对stdout的正确更改,但是,我需要更改以写入输入文件(test.stat),这样,其余字段/记录的值保持不变。有什么建议吗?

感谢。另一个问题出现了。我有一个“计数器”变量,其总和需要在END块中打印,我试过:

awk 'BEGIN {FS="\t",counter=0} 
{if($3 > 100) $3=$3/100;print else counter++}
END{print counter}' test.stat > ...

现在,只有计数器值被写入文件而不是$ 3值。如何将两个输出分开,以便使用read命令修改文件,另一个保存为bash变量。感谢。

4 个答案:

答案 0 :(得分:10)

Awk并非旨在就地编辑内容。它旨在处理数据并将其写入stdout(或其他文件)。你可以这样做:

$ awk 'BEGIN {FS="\t"} {if($3 > 100) $3=$3/100;print}' test.stat > test.stat.new \
    && mv test.stat test.stat.old && mv test.stat.new test.stat

答案 1 :(得分:2)

据我所知,awk没有按sed进行就地编辑(通过-i开关)。

当然,简单的解决方案是使用临时文件并在之后覆盖原始文件。这是即使在comp.lang.awk中推荐的解决方案。

更难的解决方案是将更改保存到awk数组,并添加一个END块,将数组内容转储到原始文件中。

答案 2 :(得分:2)

使命令更像awk:

awk -F '\t' '$3 > 100 {$3 = $3/100} {print}' test.stat

要覆盖该文件,您需要写入临时文件

f=$(mktemp)
cp test.stat test.stat.bak$(date +%s)  ;# if you want a backup copy
awk '...' test.stat > "$f" && mv "$f" test.stat

答案 3 :(得分:2)

awk 'BEGIN {FS="\t"} {if($3 > 100) $3=$3/100;print}' test.stat > /tmp/tmp.stat && mv /tmp/tmp.stat test.stat

这应该有效