Bash

如何將指定要列印的列的字元串傳遞給awk?

  • June 4, 2017

我有一個包含大量空格分隔列的文件。我想以動態方式根據某些數字標準列印特定列。例如:

]$ 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

引用自:https://unix.stackexchange.com/questions/368865