
我正在嘗試透過多變的從 shell 腳本到表格的模式識別子集的參數數量。到目前為止,這是我的嘗試:
文件“infile”:
ID,GROUP
1,GROUP2
2,GROUP2
3,GROUP4
4,GROUP4
5,GROUP5
6,GROUP5
7,GROUP23
8,GROUP23
9,GROUP23
檔案subset.sh:
#!/bin/sh
rm -f outfile_$week
week = $1
shift
for TOKEN in "$@"
do
echo "adding records for" $TOKEN
awk -F "," -v group = $TOKEN '{ if(FNR > 2 && $2 ~/group/){print $0} }' infile >> outfile_$week
done
我還嘗試過 group = "$TOKEN", "group = $TOKEN" ,然後都用單引號。我這樣提交:
sh subset.sh 061314 GROUP2 GROUP23
我得到的錯誤訊息非常少
Usage: awk [-F fs][-v Assignment][-f Progfile|Program][Assignment|File] ...
非常感謝任何幫助,謝謝!
編輯:我嘗試跑步
awk -F "," -v group ="GROUP1" '{ if(FNR > 2 && $2 ~/group/){print $0} }' infile
無濟於事...(與上面相同的錯誤)有人知道這可能發生的任何原因嗎?
答案1
你應該寫:
-v group="$TOKEN"
而不是-v group = $TOKEN
,這會導致 中的語法錯誤awk
。
答案2
聽起來像你想要的:
awk -F, '
BEGIN {
for (i = 1; i < ARGC; i++) group[ARGV[i]]
ARGC=0
}
NR >= 2 && $2 in group' "$@" < infile
或者,如果您確實想將參數視為正規表示式來匹配第二列:
awk -F, '
BEGIN {
for (i = 1; i < ARGC; i++) group[ARGV[i]]
ARGC=0
}
NR >= 2 {
for (i in group) if ($2 ~ i) {print; next}
}' "$@" < infile
答案3
您面臨的直接問題是等號周圍的空格。這個選項的參數-v
應該是一個賦值。 awk 看到 的參數-v
,後面跟著腳本 ( =
),然後是檔案名稱( 的值TOKEN
、您的腳本和您的檔案名稱)。
您在 shell 腳本中犯了類似的錯誤:week = $1
應該是week="$1"
。
順便一提,總是在指令替換兩邊加上雙引號。例如,如果TOKEN
is *
,它將被目前目錄中的檔案清單取代。
awk -v "group=$TOKEN"
不過,這不會設定group
為 的值TOKEN
,因為 awk 將賦值的右側視為 awk 語法中的文字。例如,如果 的值為TOKEN
7 個字元的字串foo\bar
,則 awk 變數group
將設定為 6 個字元的字串foo␈ar
,其中␈
是退格字元(位元組值 8)。
將變數傳遞給 awk 腳本的直接方法是將其匯出到環境中,並透過陣列使用它ENVIRON
。
此外,您沒有group
在 awk 腳本中的任何地方使用該變數。正規/group/
表示式符合包含 5 個字元的 string 的任何字串group
。如果您想檢查該欄位是否恰好等於 的值group
(例如,如果 的值TOKEN
是GROUP2
則包含的欄位GROUP24
將不會相符),請使用相等運算符==
。
export TOKEN
awk -F "," '{ if (FNR > 2 && $2 == ENVIRON["TOKEN"]){print $0} }' infile >> outfile_$week
這是整個腳本,進一步簡化為使用 awk 的條件動作語法(這裡省略了動作,因為這print $0
是預設的)並避免每次都打開輸出檔:
#!/bin/sh
week="$1"
shift
for TOKEN in "$@"
do
echo "adding records for" $TOKEN
awk -F "," 'FNR > 2 && $2 == ENVIRON["TOKEN"]' infile
done >"outfile_$week"
看斯特凡·查澤拉斯的回答使用 awk 的更高級方法不需要多次處理輸入檔。