この awk 列 2 セレクターを Bash パラメーター $1 で拡張するにはどうすればよいでしょうか?

この awk 列 2 セレクターを Bash パラメーター $1 で拡張するにはどうすればよいでしょうか?

私は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}"

現在の出力は2番目の列をキャッチできず、行全体などを取得します。

-0.21,-0.245
-0.205,-0.22

のみを使用するのprint $colNは正しくありません。 の値に関係なく、常に最初の列が使用されるためです$1

bash code.bash 2; または完全なスクリプトで呼び出す使用例こここれは、2列目の結合結果に対して、すべての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

OS: Debian 8.5
Bash 4.30

答え1

入力例では、すべてのファイルの最初のフィールドと 2 番目のフィールドに同じ値 (およびすべてのファイルで同じ値) が含まれていますが、これは正確な使用例を理解するのにはあまり役立ちません。結局のところ、同じ値を 3 回取得したい場合、任意の入力ファイルの任意のフィールドから取得できるのであれば、他の 2 つのファイルを確認する必要すらありません。次のように使用できます。

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

もちろん、これは実際の入力には機能しません。サンプル入力にのみ機能します。(このタイプの質問に対するサンプル入力/出力を改善するようにしてください。多く


次のような仮定を立てると、

  • 入力ファイルは常に3つあります
  • input1.csv、、input2.csvと呼ばれるinput3.csv
  • それぞれ2列ずつ
  • そして各ファイルの2番目の列が欲しい

pasteこれは、Awk と(およびシェル ファイルのグロビング)の組み合わせを使用すると最も簡単に実行できます。

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 ここ優れた説明付き。

関連情報