Bash
如何將指定要列印的列的字元串傳遞給awk?
我有一個包含大量空格分隔列的文件。我想以動態方式根據某些數字標準列印特定列。例如:
]$ cols=$(for i in `seq 1 3`; do echo -n "\$$[$[i-1]*6+1],\$$[$[i-1]*6+2],\$$[$[i-1]*6+3],\$$[$[i-1]*6+4+66],\$$[$[i-1]*6+5+66],\$$[$[i-1]*6+6+66],"; done)
這給了我要列印的列:
]$ echo ${cols%?} $1,$2,$3,$70,$71,$72,$7,$8,$9,$76,$77,$78,$13,$14,$15,$82,$83,$84
當我將它作為字元串傳遞給 awk 時,我沒有得到我想要的:
]$ awk -v cols=${cols%?} '{print cols}' file-testawk | head -2 $1,$2,$3,$70,$71,$72,$7,$8,$9,$76,$77,$78,$13,$14,$15,$82,$83,$84 $1,$2,$3,$70,$71,$72,$7,$8,$9,$76,$77,$78,$13,$14,$15,$82,$83,$84
awk 將其視為字元串而不是列標識符。
如何以正確辨識的方式傳遞一串列以列印到 awk?我正在尋找一種簡單的、或多或少的單線解決方案,例如:
cols=$(for i in `seq 1 3`; do echo -n "\$$[$[i-1]*6+1],\$$[$[i-1]*6+2],\$$[$[i-1]*6+3],\$$[$[i-1]*6+4+66],\$$[$[i-1]*6+5+66],\$$[$[i-1]*6+6+66],"; done); awk -v cols=${cols%?} '{print cols}' file-testawk > file.out
awk 沒有類似 eval 的功能,但您可以使用
awk -f
功能(從文件中讀取腳本)結合 bash 程序替換來製作技巧:$ a="\$1,\$4" $ echo "$a" $1,$4 $ a="{print $a}" $ echo "$a" {print $1,$4} $ awk -f <(echo "$a") <<<"one two three four five" one four
用法:
./pass_numbers_to_awk.sh
註釋中的解釋。#!/bin/bash #generate random string of numbers - simulation column's numbers for i in {1..2}; do for j in {1..3}; do num=$(( (i-1) * 6 + j )) #numbers separated by vertical bar symbol string_of_numbers+="${num}|" done done # pass to awk string like a "1|2|3|7|8|9|13|14|15|", # removing last vertical bar "|" ## # use the awk split function - for information # look at the 'man mawk | grep -A 3 split\(s,A,r\)' ## # go through array and print specified columns. awk -v string_from_bash="${string_of_numbers%?}" ' BEGIN { num_of_cols = split(string_from_bash, array_of_columns, "|"); } { for (i = 1; i <= num_of_cols; i++) { # Prevent trailing spaces emergence OFS = (i > 1) ? " " : "" printf "%s%s", OFS, $array_of_columns[i]; } printf "\n"; }' < input.txt
創建用於測試的 input.txt 文件:
./create_table.sh > input.txt
#!/bin/bash for i in {A..O}; do for j in {1..10}; do echo -n "column_${j} " done echo done