如何使用 Bash 參數 $1 擴充這個 awk 第 2 列選擇器?

如何使用 Bash 參數 $1 擴充這個 awk 第 2 列選擇器?

我試圖使我的 bash 腳本成為帶有 Bash 輸入參數的函數,但 AWK 的語法導致了問題。原始AWK程式碼

http://stackoverflow.com/a/19602188/54964
awk -F "\"*,\"*" '{print $2}' textfile.csv

帶有 Bash 參數的偽代碼$1

file=$(awk -v colN="$1" -F "\"*,\"*" '{print $"${colN}"}' "${input}") 
# http://stackoverflow.com/a/19602188/54964 
# http://stackoverflow.com/a/19075707/54964

問題出在零件print $"${colN}"

當前輸出無法捕獲第二列並佔用整行等

-0.21,-0.245
-0.205,-0.22

僅具有print $colN是不正確的,因為無論 中的值如何,它始終採用第一列$1

bash code.bash 2我用;來稱呼它的用例範例或完整的腳本這裡如果您沒有在所有兩列 CSV 檔案中對要選擇哪一列 (1/2) 進行硬編碼以取得第二列的聯結結果,則該方法有效

#!/bin/bash
ids=(101 118 201)
dir="/home/masi/Documents/CSV/"
index=0
for id in "${ids[@]}";
do
        input=$(echo "${dir}P${id}C1.csv")
        # take second column of the file here
        file=$(awk -v colN="$1" -F "\"*,\"*" '{print $colN}' "${input}") # http://stackoverflow.com/a/19602188/54964 # http://stackoverflow.com/a/19075707/54964

        Ecgs[${index}]="${file}"
        index=$index+1
done

輸入多列 1.csv 2.csv 3.csv

-0.21,-0.245
-0.205,-0.22

想要的輸出

101,118,201
-0.245,-0.245,-0.245
-0.22,-0.22,-0.22

作業系統:Debian 8.5
Bash 4.30

答案1

您的範例輸入在所有文件的第一個和第二個欄位中具有相同的值(並且所有文件的值相同),這並不能真正幫助理解確切的用例。畢竟,如果您確實想要相同的值三次並且可以從任何輸入文件的任何欄位中獲取它,您甚至不需要檢查其他兩個文件。你可以只使用:

cut -d, -f2 input.csv | paste -d, - - -

當然,這不適用於實際輸入,僅適用於您的範例輸入。 (努力改進此類問題的範例輸入/輸出,它有助於很多.)


如果我們做出假設:

  • 你總是有正好三個輸入文件
  • input1.csv, input2.csv,input3.csv
  • 每列剛好有兩列
  • 你想要每個文件的第二列

paste您可以透過 Awk 和(以及 shell 檔案通配)的組合最輕鬆地完成此操作:

paste -d, input[123].csv | awk -F, -v OFS=, '{print $2, $4, $6}'

如果這些假設是錯誤的,請歸咎於糟糕的輸入/輸出範例。 ;)

答案2

按照所述回答你的問題,鑑於

$ cat file
a,b,c
d,e,f
g,h,i
j,k,l

和一個簡單的測試腳本

$ cat col.bash
#!/bin/bash

awk -F, -vcol="$1" '{print $col}' file

您可以驗證是否$col確實引用了所需的列,即

$ ./col.bash 2
b
e
h
k

如果這對您的情況不起作用,那麼還有其他因素在起作用。無論如何,有更簡單的方法可以從多個文件中提取列。

答案3

在這種情況下使用 Bash 和 AWK 將非常困難。我無法透過此處提出的解決方案解決問題。"/ /...你將會遇到很多問題,'所以這裡需要一個工具。

gawk按照線程中討論的方式使用ECG Bash 選擇工具

# https://codereview.stackexchange.com/a/146370/122105
#!/usr/bin/gawk -f

# https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html
@include "join.awk"

BEGIN {
    FS = "\"*,\"*";
    last_row = 0;
}

BEGINFILE {
    rows[0][ARGIND] = gensub(".*P([0-9]*)C.*", "\\1", "g", FILENAME);
}

{
    rows[FNR][ARGIND] = $col;
    if (FNR > last_row) { last_row = FNR; }
}

END {
    for (r = 0; r <= last_row; r++) {
        print join(rows[r], 1, ARGC - 1, ",");
    }
}

請閱讀完整答案200_success 這裡有很好的解釋。

相關內容