我的文件很大(〜2000000行),我只想读取一次文件就试图替换几种不同的模式。
所以我猜sed不好,因为我的模式不同 我尝试将awk与if一起使用,但文件没有更改
#!/usr/bin/awk -f
{
if($0 ~ /data for AAA/)
{
sub(/^[0-9]+$/, "bla_AAA", $2)
}
if($0 ~ /data for BBB/)
{
sub(/^[0-9]+$/, "bla_BBB", $2)
}
}
我希望
的输出address 01000 data for AAA
....
address 02000 data for BBB
....
成为
address bla_AAA data for AAA
....
address bla_BBB data for BBB
....
答案 0 :(得分:1)
在您的问题中,我没有看到任何迹象表明您的文件确实很大,因为2000000行什么都不是,问题中的每个样本行都很小,所以这就是您所需要的:
awk '
/data for AAA/ { $2 = "bla_AAA"; next }
/data for BBB/ { $2 = "bla_BBB"; next }
' file > tmp && mv tmp file
GNU awk具有-i inplace
选项,可以执行与sed,perl等相同的“就地”编辑(即内部使用tmp文件)。
如果您确实没有足够的存储空间来创建输入文件的副本,则可以使用类似以下内容(未经测试!):
headLines=10000
beg=1
tmp=$(mktemp) || exit 1
while -s file; do
head -n "$headLines" file | awk 'above script' >> "$tmp" &&
headBytes=$(head -n "$headLines" file |wc -c) &&
dd if=file bs="$headBytes" skip=1 conv=notrunc of=file &&
truncate -s "-$headBytes" file
rslt=$?
done
(( rslt == 0 )) && mv "$tmp" file
因此,您所消耗的存储空间永远不会超过输入文件的大小加上headLines
行(按该数字进行处理)的大小。请参阅https://stackoverflow.com/a/17331179/1745001,以获取有关truncate
以及之前执行的两行内容的信息。
答案 1 :(得分:0)
类似的东西:
(读取一行,进行文本处理,将修改后的数据写入输出文件)
with open('in.txt') as f_in:
with open('out.txt', 'w') as f_out:
line = f_in.readline().strip()
while line:
fields = line.split(' ')
fields[1] = 'bla_{}'.format(fields[4])
f_out.write(' '.join(fields) + '\n')
line = f_in.readline()