.csvファイルの読み取りで設定された変数をパターンとして使用して、2番目の.csvファイルをgrepingします。

.csvファイルの読み取りで設定された変数をパターンとして使用して、2番目の.csvファイルをgrepingします。

2 つの .csv ファイルがあります。最初のファイルには単語のリストがあります。 2 番目のファイルには 2 つの列があり、1 番目の列には最初のファイルのエントリと一致する値が含まれます。最初のファイルを1行ずつ読み、各行を使用して2番目のファイルをgrepしたいと思います。現在のコードを表示

  1. 行を読むとき
  2. する
  3. grep $line ./filetwo.csv
  4. <fileone.csv 完了

このコードは何も生成しません。 $line をファイルを読み込んで未割り当て変数に置き換えると完璧に動作します。私は長年この問題を研究してきましたが、一見簡単に見える質問に対する答えを見つけることができませんでした。 .csvファイルを読み取って、割り当てられた変数が直接割り当てられた変数と同じ結果を提供しない理由を理解できません。 zshシェルを使用しています。

答え1

CSVファイルはMicrosoftの世界でより一般的であるため、次のものがあります。

  • ロケールの文字セットではなくUTF-16でエンコードされるため、変換が必要です。
  • あるいは、UTF-8でエンコードされていますが、バイトオーダーマークがあります。
  • CRLF 行区切り文字があります。
  • 最後の行は分離されません(したがってreadfalseが返されます)。

これが真であることを確認できますfile yourfile.csv

これにより、次のことができます。

dos2unix < fileone.csv |
  while IFS=, read -r first rest_if_any_ignored; do
    dos2unix < filetwo.csv | grep -Fe "$first"
  done

(正規表現マッチング-Fを実行するデフォルトではなく固定文字列検索に注意してください。)しかし、これは各行に対して3つのコマンドを実行し、各コマンドが毎回最初から内容を処理するため、かなり非効率的です。regrepfileone.csvgrepfiletwo.csv

$firstまた、最初の列だけでなく、任意の場所で文字列を検索し、filetwo.csv正確な一致を実行しません。たとえば、$firstisのfoo場合とfoobar,otherother,foobarが報告されます。これはCSV参照も処理しません。したがって、適切なCSV解析機能を持つ言語を使用することをお勧めします。

これらのファイルに単純なCSV、つまり参照やヘッダーがない場合は、次の操作が行われますjoin

preprocess() {
  dos2unix -O -- "$@" | sort -t, -k1b,1
}

join -t, <(preprocess < fileone.csv) <(preprocess < filetwo.csv)

ヘッダーと可能な引用符(改行を含むデータを含む)を持つ実際のCSVのmlr場合は、CSVパーサーを使用できます。そのjoin動詞

fooたとえば、最初の列がinfileone.csvbarinで呼び出された場合filetwo.csv

mlr --csv join -j foo -r bar -f fileone.csv filetwo.csv

dos2unixCRLF、無制限の行、およびBOMを持つUTF-8を処理できますが、UTF-16は処理できません。まず、UTF-8を使用するか、UTF-8に変換する必要がありますiconv

mlr単純なCSVや他のいくつかのテーブル形式も実行できます。詳細については、該当するマニュアルを参照してください。

関連情報