CSVから複数の値を取得し、その値から関連する値を取得します。

CSVから複数の値を取得し、その値から関連する値を取得します。

ファイル.csv

"ItemNo","Name","Weight"
"a001","Item a","1.1"
"a002","Item x","1.2"
"a003","Item_4","1.0"
"a004","Item b","1.1"
"a005","Itemb2","2.0"
"a006","a004","2.0"

もう少しあります。プロジェクト番号.csv

"a003"
"a001"
"a004"

「ItemNo」に関連付けられている「名前」リストを生成するコマンドを探しています...

だから私の出力.csvしなければならない

"Item_4"
"Item a"
"Item b"

誰でも助けることができますか?


最初の列のfile.csvの各item.noは一意です。しかし、a001、a001-b1、a001-b2などがあります。しかし、「a001」、「a001-b1」を検索すると、すべてが再び一意である必要があります。

特定のツールは必要ありません。すべての便利なソリューションが必要です。しかし、最初の行だけを検索すると良いでしょう(ItemNo「a006」(列1)のItem.Nameが「a004」(列2)であると仮定)。


私は前に試しましたgrepコマンド

grep -f itemno.csv file.csv | awk -F, '{print $2}'

しかし、結果最後の行の出力は次のようになります。

"Item b"

私は前に試しましたawkコマンド

awk -F, 'NR==FNR{a[$1]; next} $1 in a{print $2}' itemno.csv file.csv

しかし、結果最後の行の出力は次のようになります。

"Item b"

たぶん命令を繰り返す方が良い考えでしょうか?

だから私は努力しました今回のサイクル

while read -r line; do
    grep "${line}" file.csv | awk -F "," '{print $2}';
done < itemno.csv 

しかしそこには出力なし...まるで各行の後に別の行が続くように\アル字型

だから私は努力しましたこのコマンド

while read line; do
    grep $(printf ${line} | sed 's/\r//g') file.csv | awk -F "," '{print $2}';
done < itemno2.csv 

これでプロジェクト番号2.csv

"a003"
"a001"
"a002"
"a004"

そして出力以前は:

"Item a"
"Item x"

この奇妙な反復コマンドでのみItemNumberを取得できます(そして、コマンドは最初の行と最後の行を無視します)。

ベストアンサー1

入力データはCSVファイルとヘッダーなしのCSVファイルです。

後で名前で含めたいフィールドを参照できるように、ヘッダーなしのCSVファイルにヘッダーを追加することから始めますItemNo。私たちはこれを通してミラーmlr)、untitledモードを使用してデータを読み取り、--implicit-csv-headerサブlabelコマンドを使用してItemNo最初の列にラベルを追加します。

$ mlr --csv --implicit-csv-header label ItemNo itemno.csv
ItemNo
a003
a001
a004

Millerを使用すると、最初の行からラベルを選択するの--implicit-csv-headerではなく、内部で最初のフィールドにラベルを付けます。1その後、サブコマンドはlabelそれをに変更しますItemNo

出力のデータが引用されていないという事実は、引用する必要がないため重要ではありません(含まれている区切り文字や改行文字などは含まれません)。 Miller は、引用が必要なフィールドを自動的に引用します。

joinその後、Millerの作業に使用できます。

$ mlr --csv --implicit-csv-header label ItemNo itemno.csv | mlr --csv join -f file.csv -j ItemNo
ItemNo,Name,Weight
a003,Item_4,1.0
a001,Item a,1.1
a004,Item b,1.1

ItemNoこれは、入力データフィールドfile.csvmlrパイプラインの最初のコマンドデータとの間でリレーショナル「内部結合」操作を実行します。

cutその後、抽出されたフィールドに対して文字列操作を実行できますName

$ mlr --csv --implicit-csv-header label ItemNo itemno.csv | mlr --csv join -f file.csv -j ItemNo then cut -f Name
Name
Item_4
Item a
Item b

--headerless-csv-output質問にヘッダーなしのCSV出力を取得できることを追加し、--quote-allそれを行う必要がなくてもMillerがすべての出力フィールドを引用するように強制できます。

$ mlr --csv --implicit-csv-header label ItemNo itemno.csv | mlr --csv --headerless-csv-output --quote-all join -f file.csv -j ItemNo then cut -f Name
"Item_4"
"Item a"
"Item b"

Millerは、入力ファイルがDOSであるかUnixテキストファイルであるかは関係ありません。複雑なフィールドを持つCSVファイルを解析できます。

おすすめ記事