web-dev-qa-db-ja.com

あるファイルの内容を別のファイルで見つける

次のシェルスクリプトを使用して、あるファイルの内容を別のファイルに移動しています。

#!/bin/ksh
file="/home/nimish/contents.txt"

while read -r line; do
    grep $line /home/nimish/another_file.csv
done < "$file"

スクリプトを実行していますが、csvファイルの内容が表示されません。私のcontents.txtファイルには、csvファイルにも存在する"08915673""123223"などの番号が含まれています。私が間違っていることはありますか?

10

grep自体はそうすることができます。フラグ-fを使用するだけです。

grep -f <patterns> <file>

<patterns>は、各行に1つのパターンを含むファイルです。 <file>は、検索するファイルです。

grepに各行をパターンと見なさせるには、各行の内容が正規表現のように見えても、フラグ-F, --fixed-stringsを使用する必要があります。

grep -F -f <patterns> <file>

あなたが言ったようにあなたのファイルがCSVであるならば、あなたはそうするかもしれません:

grep -f <(tr ',' '\n' < data.csv) <file>

例として、次の行を含むファイル "a.txt"を考えます。

alpha
0891234
beta

次の行を含むファイル「b.txt」:

Alpha
0808080
0891234
bEtA

次のコマンドの出力は次のとおりです。

grep -f "a.txt" "b.txt"
0891234

ここでfor- loopを実行する必要はまったくありません。 grep自体がこの機能を提供します。


次にファイル名を使用します。

#!/bin/bash
patterns="/home/nimish/contents.txt"
search="/home/nimish/another_file.csv"
grep -f <(tr ',' '\n' < "${patterns}") "${search}"

','をファイル内のセパレーターに変更できます。

32
Rubens

別の解決策:

  • awkを使用して、独自のhash(ahashなど)を作成し、すべて自分で制御します。
  • $0 to $iを置き換えます。任意のフィールドを照合できます。

awk -F"," '
{  
   if (nowfile==""){ nowfile = FILENAME;  }

   if(FILENAME == nowfile)
   {
     hash[$0]=$0;
   }
   else
   {
       if($0 ~ hash[$0])
       {  
           print $0
       }
   }
} '  xx yy
2
sharingli

あなたがやろうとしていることを実行するためのスクリプトは本当に必要ないと思います。

1つのコマンドで十分です。私の場合、csvファイルの列11に識別番号が必要です(区切り文字として「;」を使用)

grep -f <(awk -F";" '{print $11}' FILE_TO_EXTRACT_PATTERNS_FROM.csv) TARGET_FILE.csv 

これがお役に立てば幸いです。

1