내 운영 체제: 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"