![參考](https://rvso.com/image/192228/%E5%8F%83%E8%80%83.png)
我使用過的典型 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,則預設為列印;然後不區分大小寫地與和進行比較1
IGNORECASE
$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
) 支援它 - 為了可移植性,您可以使用它toupper
或tolower
將輸入獲取到特定的情況。
答案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 的結果進行正規表示式比較,該結果始終為 true,因此它會列印當前行。然後,它在該行的任何位置查找與正規表示式匹配的任何字串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 |
- 設定 shell 變數
pattern
- 德利姆將 TSV 轉換為 CSV
- 篩選在第 2 列上-我 大小寫不變 --正規表示式該 shell 變數的
- 斬首只獲取匹配的行
- 轉換回 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