我已经尝试了很多方法,但仍然无法达到我想要的效果。抱歉我还在学习。
我想要的是这样的:
文件A.txt
5844
6069
6303
6309
文件B.txt
// some comment
// some explanation
100,5,3,8,,,
500,5,44,8,,,
//2500,5,2,8,,,
2121,5,2,8,,,
5535,5,4,6069,,,
5844,1,4,5844,,,
5900,5,2,8,,,
6069,5,4,8,,,
我想更改 A.txt 中搜索到的数字并注释掉 B.txt 中的行。有时搜索到的数字可能会出现在另一列中,因此只会更改第一列。
结果:
// some comment
// some explanation
100,5,3,8,,,
500,5,44,8,,,
2500,5,2,8,,,
2121,5,2,8,,,
5535,5,4,6069,,,
//5844,1,4,5844,,,
5900,5,2,8,,,
//6069,5,4,8,,,
我尝试过,有时它会变得混乱并且也更改了其他列。然后我就用了这样的东西,很长而且不好修改,
awk -F ',' '/^5844/ && $1="5844"{$1="//5844"}1' b.txt > c.txt; cp c.txt ba.txt; rm -rf b.txt; mv ba.txt b.txt
有时还会删除“,”分隔符。
请帮忙,非常感谢。
答案1
$ awk -F , 'FNR==NR { data[$1]=1; next } $1 in data { $0 = "//" $0 }; 1' 'File A.txt' 'File B.txt'
500,5,4,8,,,
5535,5,4,6069,,,
2121,5,4,8,,,
//5844,5,4,5844,,,
//6069,5,4,8,,,
File A.txt
我在这里所做的是首先从关联数组中的键中读取数字data
。然后,我测试每个第一个字段,File B.txt
看看它是否是关键字段data
。如果是,我会添加//
到当前行的前面。然后打印所有行,无论是否修改。
仅当从命令行上的第一个文件读取时,测试FNR==NR
才会为真,并且该块以next
.这意味着,如果第一个字段是数组中的键,则仅对第一个文件执行第一个块,而对第二个文件执行第二个块data
。
最后1
的 触发输出,可以用 代替{ print }
。
以上只会添加 //
到第二个文件中与第一个文件中的数字匹配的行。至也消除 //
从行不是匹配(即处理您更新的问题):
$ cat 'File B.txt'
// some comment
// some explanation
100,5,3,8,,,
500,5,44,8,,,
//2500,5,2,8,,,
2121,5,2,8,,,
5535,5,4,6069,,,
5844,1,4,5844,,,
5900,5,2,8,,,
6069,5,4,8,,,
$ awk -F , 'FNR==NR { data[$1]=1; next } FNR > 2 { if ($1 in data) $0 = "//" $0; else sub("^//","") }; 1' 'File A.txt' 'File B.txt'
// some comment
// some explanation
100,5,3,8,,,
500,5,44,8,,,
2500,5,2,8,,,
2121,5,2,8,,,
5535,5,4,6069,,,
//5844,1,4,5844,,,
5900,5,2,8,,,
//6069,5,4,8,,,
该awk
命令假设您希望不File B.txt
更改地通过前两行(这是FNR > 2
测试所负责的)。该FNR > 2
块测试该数字是否是一个键data
,如果是,则该行被注释掉,但如果不是,则//
使用 删除该行开头的任何内容sub()
。
FNR > 2
您可以使用/^\/\/ /
测试文件顶部的注释来代替。这将要求所有此类注释始终//
以空格开头。
特殊变量NR
和保存到目前为止总共 ( ) 和当前文件 ( ) 中FNR
读取的行数。NR
FNR
如果我仅更改第一个字段,则逗号将“消失”,$1 = "//" $1
因为这将使用当前值OFS
(默认为空格)重新形成记录。您可以通过使用 来防止这种情况BEGIN { OFS=FS }
,它将设置OFS
为逗号字符(或您-F
在命令行上使用的任何字符)。