특정 열을 사용하여 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의 두 번째 열에는 공백이 없는 고유한 문자열이 있습니다. 그렇게 부르자uid

• 중요하지는 않지만 언급하자면 더 많은 제목이 있을 수 있고 각 제목 아래에는 수천 개의 항목이 있을 수 있습니다.

목표 1:Yesterday.txt에 없는 Today.txt 파일에서 새 항목을 찾으려면 uid(두 번째 열)을 사용하세요.

이 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"

관련 정보