参考

参考

我使用过的典型 tsv 文件的片段

10  Interstellar    Main Theme Extended UDVtMYqUAyw
11  Journey XvG78AmBLc4
12  Jurassic Park Music & Ambience  Amazing Soundscapes and Music   PPl__iyIg6w
13  Lord of the Rings   Sound of The Shire  chLZQtCold8
14  Lord of the Rings   The Shire: Sunset at Bag End    uBmbI8dzc-M

以下在所有 tsv 文件的第二列中搜索 lord(不区分大小写):

awk '$2~IGNORECASE = 1;/lord/{print}' *.tsv 

13      Lord of the Rings       Sound of The Shire      chLZQtCold8
14      Lord of the Rings       The Shire: Sunset at Bag End    uBmbI8dzc-M

现在,我想Lord作为 bash 环境变量传递:

$ awk -v Pattern="Lord" '$2~Pattern{print}' *.tsv 
13      Lord of the Rings       Sound of The Shire      chLZQtCold8
14      Lord of the Rings       The Shire: Sunset at Bag End    uBmbI8dzc-M

问题

如何不区分大小写地进行模式匹配?

我尝试了以下方法,但它不起作用

awk -v Pattern="lord" '$2~IGNORECASE = 1;Pattern{print}' *.tsv

awk -v Pattern="lord" 'IGNORECASE = 1;$2~Pattern{print}' *.tsv

awk -v Pattern="lord" 'BEGIN {IGNORECASE = 1}  {$2~Pattern{print}}' *.tsv 

awk -v Pattern="Lord" '{IGNORECASE = 1; $2~Pattern}' *.tsv 

参考

答案1

首先,我怀疑它的工作方式是否像你想象的那样 - AFAIK 它为变量$2~IGNORECASE = 1;/lord/{print}赋值;将 的值与结果(即)进行比较,如果结果为 true,则默认打印;然后不区分大小写地与和进行比较1IGNORECASE$2$2 ~ 1$0$0/lord/$0如果这是真的,则打印。

如果您的目的是$2不区分大小写进行比较,您可以使用

gawk 'BEGIN{IGNORECASE = 1} $2 ~ /lord/{print}` *.tsv

要不就

gawk 'BEGIN{IGNORECASE = 1} $2 ~ /lord/` *.tsv

变量的等价物是

gawk -v Pattern="lord" 'BEGIN{IGNORECASE = 1} $2 ~ Pattern' *.tsv

请注意,这IGNORECASE不是标准的 awk 功能 - 据我所知,只有 GNU awk ( gawk) 支持它 - 为了可移植性,您可以使用touppertolower将输入获取到特定情况。

答案2

关于The following searches for lord (case insensitively) in 2nd column of all tsv files: awk '$2~IGNORECASE = 1;/lord/{print}' *.tsv- 不,它根本不会这样做。它对 $2 进行正则表达式比较,并将 IGNORECASE 赋值为 1 的结果与此结果进行比较,该结果始终为真,因此它会打印当前行。然后,它会lord在该行的任意位置查找与正则表达式匹配的任何字符串,如果找到,则会再次打印该行。您可能打算awk 'BEGIN{IGNORECASE = 1} $2~/lord/' *.tsv这样做,因为这样做会达到您所描述的效果。

不要在这种情况下使用“模式”一词,因为它的含义非常模糊。您使用 Pattern 作为部分正则表达式匹配,但将其描述为好像您想要全字字符串匹配。因此,请将“模式”替换为您问题中出现的所有 3 个字符串或正则表达式、部分或完整以及单词或行,以便我们可以帮助您找到正确的解决方案。看如何找到与模式匹配的文本了解更多信息。

以下是您可能尝试执行的操作的一些可能的解决方案:

部分字符串匹配:

$ awk -v var="$var" -F'\t' 'index(tolower($2),tolower(var))' file.tsv
13  Lord of the Rings   Sound of The Shire  chLZQtCold8
14  Lord of the Rings   The Shire: Sunset at Bag End    uBmbI8dzc-M

全字字符串匹配:

$ awk -v var="$var" -F'\t' 'index(" "tolower($2)" ",tolower(var))' file.tsv
13  Lord of the Rings   Sound of The Shire  chLZQtCold8
14  Lord of the Rings   The Shire: Sunset at Bag End    uBmbI8dzc-M

全行字符串匹配:

$ awk -v var="$var" -F'\t' 'tolower($2) == tolower(var)' file.tsv
$

部分正则表达式匹配:

$ awk -v var="$var" -F'\t' 'tolower($2) ~ tolower(var)' file.tsv
13  Lord of the Rings   Sound of The Shire  chLZQtCold8
14  Lord of the Rings   The Shire: Sunset at Bag End    uBmbI8dzc-M

全字正则表达式匹配:

$ awk -v var="$var" -F'\t' '(" "tolower($2)" ") ~ tolower(var)' file.tsv
13  Lord of the Rings   Sound of The Shire  chLZQtCold8
14  Lord of the Rings   The Shire: Sunset at Bag End    uBmbI8dzc-M

全行正则表达式匹配:

$ awk -v var="$var" -F'\t' 'tolower($2) ~ ("^"tolower(var)"$")' file.tsv
$

上面假设您的 shell 变量不包含转义序列,或者如果包含,您希望它们扩展。如果不是这种情况,则使用ENVIRON[]orARGV[]将 shell 变量的值传递给 awk 而不是-v,请参阅如何在 awk 脚本中使用 shell 变量了解详情。

答案3

perl

在文件的第二个字段中搜索模式:

perl -F"\t" -lane '$F[1] =~ /(?i)lord/ and print' input.tsv
  • -F"\t"是因为文件是 tsv
  • $F[1]是第二个记录文件,因为字段是零索引的。
  • (?i)正则表达式中的选项不区分大小写
  • 或修饰符i可用于不区分大小写,如
perl -F"\t" -lane '$F[1] =~ /lord/i and print' input.tsv

export匹配 shell 变量的正则表达式可以通过如下方式完成

export p=lord
perl -F"\t" -lane '$F[1] =~ /(?i)$ENV{p}/ and print' input.tsv
perl -F"\t" -lane '$F[1] =~ /$ENV{p}/i and print' input.tsv

搜索.tsv文件夹中的所有文件:

perl -F"\t" -lane '$F[1] =~ /$ENV{p}/i and print' *.tsv

如果您想要带有记录的文件名,则可以执行以下操作:

perl -F"\t" -lane '$F[1] =~ /$ENV{p}/i and print $ARGV. ":" .$_' *.tsv

答案4

如果你不需要使用awk并且可以使用专用于处理表格数据的工具,例如GoCSV,这是一个快照。

从您提供的数据样本开始,我编了一些名字并猜测了“旅程”:

输入.tsv

ID 专辑 追踪 哈希值
10 星际穿越 主题扩展 UDVtMYqUAyw
11 旅行 XvG78AmBLc4
12 侏罗纪公园音乐和氛围 令人惊叹的音景和音乐 PPl__iyIg6w
13 指环王 夏尔之声 chLZQtCold8
14 指环王 夏尔:袋底洞的日落 uBmbI8dzc-M
  1. 设置 shell 变量pattern
  2. 德利姆将 TSV 转换为 CSV
  3. 筛选在第 2 列上-我 大小写不变 --正则表达式该 shell 变量
  4. 斩首只获取匹配的行
  5. 转换回 TSV:
pattern='lord'
gocsv delim -i "\t" input.tsv              \
| gocsv filter -c 2 -i --regex "$pattern"  \
| gocsv behead                             \
| gocsv tsv

13      Lord of the Rings       Sound of The Shire      chLZQtCold8
14      Lord of the Rings       The Shire: Sunset at Bag End    uBmbI8dzc-M

相关内容