遇到个处理文本文件的问题


cat test.txt

"355356" "1700870" "1" "0202" ""

"355356" "1700871" "2" "" "02046" 

"355356" "1700870" "" "2" "02046" 

"1700870" "1700873" "" "1" "0202" 

把第2列是1700870的数据改为1700888


起初我得想法是直接用sed


sed -i "s/1700870/1700888/g" test.txt     //替换每行的所有匹配


得到数据如下,一开始我认为这种方法并无问题,可后来发现犯了很傻的错误。 第一列的最后一个字段也被替换了。

"355356" "1700888" "1" "0202" ""

"355356" "1700871" "2" "" "02046" 

"355356" "1700888" "" "2" "02046" 

"1700888" "1700873" "" "1" "0202" 

后来用awk去解决这个问题


思路是对第二列等于1700870的行做处理


awk -F "\"" '{if ($4==1700870) $4=1700888}' test.txt 

什么结果都没有打印,后来在网上搜了一下,想打印处理过的文本要么用print,要么在最后加个1,如下:


awk -F "\"" '{if ($4==1700870) $4=1700888}1' test.txt


结果如下


355356 1700888 1 0202 

"355356" "1700871" "2" "" "02046" 

355356 1700888 2 02046 

"1700870" "1700873" "" "1" "0202" 

不知道为什么”“没了,准定不符合规则,原因是在awk处理每一行数据的时候会把输出分隔符用默认的”空格“代替,所以我们发现每个


处理过的行都没了”“。


搜索了一下awk的用法,可以在输出时候自己指定输出分隔符。


awk -F "\"" '{OFS="\""} {if ($4==1700870) $4=1700888}1' test.txt 

结果如下符合需求:

"355356" "1700888" "1" "0202" ""

"355356" "1700871" "2" "" "02046" 

"355356" "1700888" "" "2" "02046" 

"1700870" "1700873" "" "1" "0202"


但上面的awk语法太难看,所以改进一下


awk 'BEGIN{FS=OFS="\""} {if ($4==1700870) $4=1700888}1' test.txt 

把定义的输入和输出字符放到BEGIN里面,增强了程序的可读性。