从“txt A”中搜索数字并替换为 csv 文件

从“txt A”中搜索数字并替换为 csv 文件

我已经尝试了很多方法,但仍然无法达到我想要的效果。抱歉我还在学习。

我想要的是这样的:

文件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读取的行数。NRFNR


如果我仅更改第一个字段,则逗号将“消失”,$1 = "//" $1因为这将使用当前值OFS(默认为空格)重新形成记录。您可以通过使用 来防止这种情况BEGIN { OFS=FS },它将设置OFS为逗号字符(或您-F在命令行上使用的任何字符)。

相关内容