繁体   English   中英

连接黑名单以在 CSV 文件中用作 AWK gsub 正则表达式

[英]Concatenating black-list to use as AWK gsub regex in CSV file

我正在尝试使用脚本从 CSV 文件的特定列中删除 blacklist.txt 文件中出现的任何字符串。

通过许多版本的反复试验,我发现以下 AWK 正则表达式可以在不匹配子字符串的情况下工作。

将换行符分隔的 txt 文件转换为正则表达式: list="$(cat blacklist.txt | tr "\n" "|" | sed 's/.$//')"

这给出了类似于此的 output: already|also|although|always|am|among|amongst|amoungst|amount|an|and|another|any|anyhow|anyone|anything|anyway|anywhere

然后我尝试在 awk 替换命令中使用此变量,使用"\\<(word|word)>\\ *"正则表达式格式以避免 substring 匹配。

这看起来如下:

awk -F, -v list=$list 'BEGIN{ re = "\x22\\\\<("list")\\\\> *\x22"} { gsub(re,"", $2);} 1 ' OFS=',' test.csv

这本身不起作用。 但是,如果我打印从此命令生成的正则表达式:

awk -F, -v list=$list 'BEGIN{ re = "\x22\\\\<("list")\\\\> *\x22"} { gsub(re,"", $2); print re} 1 ' OFS=',' test.csv

我得到一个re的格式:

"\\<(a|about|above|across|after|afterwards|again|against|all|almost|alone|along|already|also|although|always|am|among|amongst|amoungst|amount|an|and|another|any|anyhow|anyone|anything|anyway|anywhere)\\> *"

如果我将其复制并粘贴到 awk 命令中,替换 gsub 中的re变量,那么它可以工作!

当作为正则表达式粘贴的变量的直接 output 确实有效时,我无法弄清楚为什么正则表达式不能作为变量工作。

样品 CSV

foobar,a house car,a foobar, foobar foobar
foobar,a house car,a foobar, foobar foobar
foobar,a house car,a foobar, foobar foobar
foobar,a house car,a foobar, foobar foobar

使用变量的命令中的 output 不正确

awk -F, -v list=$list 'BEGIN{ re = "\x22\\\\<("list")\\\\> *\x22"} { gsub(re,"", $2);} 1 ' OFS=',' test.csv
foobar,a house car,a foobar, foobar foobar
foobar,a house car,a foobar, foobar foobar
foobar,a house car,a foobar, foobar foobar
foobar,a house car,a foobar, foobar foobar

使用变量内容从命令中纠正 output

awk -F, -v list=$stop_word_list '{ gsub("\\<(a|about|above|across|after|afterwards|again|against|all|almost|alone|along|already|also|although|always|am|among|amongst|amoungst|amount|an|and|another|any|anyhow|anyone|anything|anyway|anywhere)\\> *","", $2);} 1 ' OFS=',' test.csv
foobar,house car,a foobar, foobar foobar
foobar,house car,a foobar, foobar foobar
foobar,house car,a foobar, foobar foobar
foobar,house car,a foobar, foobar foobar

请注意,“a”从第二列中消失了,但没有从第三列中消失,并且“car”内部的 a 也不匹配。

请注意,blacklist.txt 文件比我在此处提供的文件要长一些,并且我没有在列入黑名单的单词中进行硬编码的选项,因为它们可能会被换出。

在 OP 的代码中, re = "\x22...\x22"将实际的双引号嵌入到变量re中,这反过来又告诉gsub()$2中查找实际的双引号。

虽然剥离\x22可能会有所帮助,但我将选择一种稍微不同的方法......


一种在gsub()调用中构建正则表达式的awk解决方案:

list='a|about|above|across|after'

awk -v list="${list}" 'BEGIN {FS=OFS=","} {gsub("\\<("list")\\> *","",$2)} 1' test.csv

这会产生:

foobar,house car,a foobar, foobar foobar
foobar,house car,a foobar, foobar foobar
foobar,house car,a foobar, foobar foobar
foobar,house car,a foobar, foobar foobar

如果 OP 在一些地方需要正则表达式,我们仍然可以使用以下内容构建re变量:

awk -v list="${list}" 'BEGIN {FS=OFS=","; re="\\<("list")\\> *"} {gsub(re,"",$2)} 1' test.csv

这也产生:

foobar,house car,a foobar, foobar foobar
foobar,house car,a foobar, foobar foobar
foobar,house car,a foobar, foobar foobar
foobar,house car,a foobar, foobar foobar

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM