特定の列を使用して2つのCSVファイルを比較し、特定の文字列を無視します。

特定の列を使用して2つのCSVファイルを比較し、特定の文字列を無視します。

私のオペレーティングシステム:RHEL7.X

以下のように、3つの列を含むCSVファイルがあります。

#######Category: Fruit
Berries are fruit,04415bef-8c82-4672-848a-9ac80035040a,"Blah/Blah  And/More/Blah"
Apple is a fruit,073c6bf3-74d2-4c20-b8a7-82625cffe256,"Blah1.0/Blah  And/More/Blah2.0"
Orange is a fruit,083dddd7-2df4-422a-a07b-00419ccf98fd,"Blah2.0/Blah  And/More/Blah2.1"
---
---
#######Category: Vegetable
Sprouts are vegetable,84e0a0d8-0c0e-448b-9ad6-21178dac8b86,"Blah/Blah  And/lot More/Blah"
Ginger is a vegetable,abb5fee2-a588-45a7-a8c0-9cd87d60a6d2,"Blah1.0/Blah  And/whole lot more/Blah2.0"
onions is a vegetable,baeee94a-6447-4c80-bddf-313e0fc144a7,"Blah2.0/Blah  And/Lot More/Blah2.1"
---
---
#######Category: Mixed
Tomatoes can be called a mix,fe31c693-cdf4-4171-9c80-7a297d4bdb96,"Blah/Blah And/More/Blah"
cucumber is a joke,d3540c7f-fea5-4e64-87df-c18fdb0b7ff3,"Blah1.0/Blah  And/More/Blah2.0"
Spinach is LOL,da816135-9852-4067-8780-4e504dc8084b,"Blah2.0/Blah  And/Even More/Blah2.1"
---
---

•上記のデータはファイルからのものです。

•各タイトルの下に追加のエントリを含む新しいCSVが毎日作成されます。

•ヘッダの例:#######Category: Fruit

  • 上記の例では、「---」はより多くの項目を表します。何千ものアイテムがあるかもしれません。

•タイトル(「#」で始まる)は毎日変わりません。

• 毎日新しいデータが収集され、ファイルにダンプされます。今日のデータがファイルにダンプされたとします。/path/to/Today.txt

•24時間のデータがファイルにダンプされました。/path/to/Yesterday.txt

•このcsvの2番目の列には、空白のない一意の文字列があります。そう呼ぶuid

•重要ではありませんが、言及すると、より多くのタイトルがあり、各タイトルの下に何千ものアイテムがある可能性があります。

目標1:Yesterday.txtにないToday.txtファイルで新しいエントリを見つけるには、uid(2番目の列)を使用してください。

このbashコードの機能は次のとおりです。

TodayFile=/path/to/Today.txt
YstdayFile=/path/to/Yesterday.txt

sed -e '/^\s*$/ d' -e '/^#/ d' $TodayFile | awk -F , '{print $2}' | sed '/^$/d' | while read uid; do

        if [[ -z $(grep $uid $YstdayFile) ]];then
            grep $uid $TodayFile >> NewEntries.txt
        fi
done

新しく作成されたアイテムを開くと、存在しないNewEntries.txt新しいアイテムが表示されます。/path/to/Yesterday.txt

cat -n NewEntries.txt

1 new entry
2 new entry
3 new entry
---
---

しかし、この出力は十分ではありません。

目標は次のとおりです。新しいアイテムを見つけて、タイトル(そのアイテムが属する場所)を完全かつ体系的に維持します。

シミュレーションの最終出力は次のようになります。

#######Category: Fruit
new entry
new entry
---
---
#######Category: Vegetable
new entry
new entry
---
---
#######Category: Mixed
new entry
new entry
---
---

新しいアイテム(存在する場合)が関連タイトルの下に表示されます。

シェル/バッシュスクリプトを使用してこれを達成するにはどうすればよいですか?どんな提案がありますか?

ループを実行するよりも簡単な解決策はありますか?

ベストアンサー1

仮定:

  • すべてYesterday.txt含まれていますToday.txt
  • 最初の列にはコンマが含まれていません。

この特別な場合はすでに使用しているため、単一のスクリプトでプロセス全体を作成awkできます。awkこれにより、コードの複雑さが減り、パフォーマンスが大幅に向上します(特に大容量ファイルの場合)。

設定(3つのカテゴリのそれぞれの末尾に新しい行を追加):

$ cat Yesterday.txt
#######Category: Fruit
Berries are fruit,04415bef-8c82-4672-848a-9ac80035040a,"Blah/Blah  And/More/Blah"
Apple is a fruit,073c6bf3-74d2-4c20-b8a7-82625cffe256,"Blah1.0/Blah  And/More/Blah2.0"
#######Category: Vegetable
Sprouts are vegetable,84e0a0d8-0c0e-448b-9ad6-21178dac8b86,"Blah/Blah  And/lot More/Blah"
Ginger is a vegetable,abb5fee2-a588-45a7-a8c0-9cd87d60a6d2,"Blah1.0/Blah  And/whole lot more/Blah2.0"
#######Category: Mixed
Tomatoes can be called a mix,fe31c693-cdf4-4171-9c80-7a297d4bdb96,"Blah/Blah And/More/Blah"
cucumber is a joke,d3540c7f-fea5-4e64-87df-c18fdb0b7ff3,"Blah1.0/Blah  And/More/Blah2.0"

$ cat Today.txt
#######Category: Fruit
Berries are fruit,04415bef-8c82-4672-848a-9ac80035040a,"Blah/Blah  And/More/Blah"
Apple is a fruit,073c6bf3-74d2-4c20-b8a7-82625cffe256,"Blah1.0/Blah  And/More/Blah2.0"
Orange is a fruit,083dddd7-2df4-422a-a07b-00419ccf98fd,"Blah2.0/Blah  And/More/Blah2.1"
#######Category: Vegetable
Sprouts are vegetable,84e0a0d8-0c0e-448b-9ad6-21178dac8b86,"Blah/Blah  And/lot More/Blah"
Ginger is a vegetable,abb5fee2-a588-45a7-a8c0-9cd87d60a6d2,"Blah1.0/Blah  And/whole lot more/Blah2.0"
onions is a vegetable,baeee94a-6447-4c80-bddf-313e0fc144a7,"Blah2.0/Blah  And/Lot More/Blah2.1"
#######Category: Mixed
Tomatoes can be called a mix,fe31c693-cdf4-4171-9c80-7a297d4bdb96,"Blah/Blah And/More/Blah"
cucumber is a joke,d3540c7f-fea5-4e64-87df-c18fdb0b7ff3,"Blah1.0/Blah  And/More/Blah2.0"
Spinach is LOL,da816135-9852-4067-8780-4e504dc8084b,"Blah2.0/Blah  And/Even More/Blah2.1"

アイデアawk

awk -F',' '
FNR==NR { seen[$2]; next }              # 1st file: save 2nd column (uid) as index in array seen[]
/^#####/ || !($2 in seen)               # 2nd file: if line starts with "#####" or 2nd field is not an index in array seen[], then print current line to stdout
' Yesterday.txt Today.txt

これで以下が生成されます。

#######Category: Fruit
Orange is a fruit,083dddd7-2df4-422a-a07b-00419ccf98fd,"Blah2.0/Blah  And/More/Blah2.1"
#######Category: Vegetable
onions is a vegetable,baeee94a-6447-4c80-bddf-313e0fc144a7,"Blah2.0/Blah  And/Lot More/Blah2.1"
#######Category: Mixed
Spinach is LOL,da816135-9852-4067-8780-4e504dc8084b,"Blah2.0/Blah  And/Even More/Blah2.1"

おすすめ記事