다양한 파일을 병합/정렬하고 헤더를 맨 위에 유지

다양한 파일을 병합/정렬하고 헤더를 맨 위에 유지

다음과 같이 세 가지 파일 세트가 있습니다.

cat "110001_test file_first_file.csv"
ID,NAME,LOCATION
1,Vikrant,Gurgaon
2,Bharat,Noida
3,Raju,Hyderabad

cat "110001_test file_second_file.csv"
ID,NAME,LOCATION
1,Vikrant,Gurgaon
22,abcd,Noida
3,Raju,Hyderabad

cat "110001_test file_third_file.csv"
ID,NAME,LOCATION
1,Vikrant,Gurgaon
2,Bharat,Noida
33,xyz,Hyderabad

아래 명령을 사용하여 이러한 파일을 병합하고 헤더를 맨 위에 한 번 유지하고 중복된 항목이 있는 경우 제거했습니다.

find . -type f -name '*test file*.csv' -exec cat {} + | awk 'NR == 1; NR > 1 {print $0 | "sort -u"}' > output.file

나에게 제공되는 결과는 다음과 같습니다.

ID,NAME,LOCATION
1,Vikrant,Gurgaon
22,abcd,Noida
2,Bharat,Noida
33,xyz,Hyderabad
3,Raju,Hyderabad
ID,NAME,LOCATION

나는 여기서 무슨 일이 일어나고 있고 명령이 무엇을 하는지 이해합니다. 기본적으로 첫 번째 행을 무시하고 다른 레코드를 선택하여 그 안의 중복 항목을 정렬하고 제거합니다. 따라서 출력 파일 하단에 추가 헤더가 표시됩니다.

이런 출력을 기대하고 있습니다.

ID,NAME,LOCATION
1,Vikrant,Gurgaon
22,abcd,Noida
2,Bharat,Noida
33,xyz,Hyderabad
3,Raju,Hyderabad

답변1

사용 및 bash:headtailsort

파일 이름을 배열로 저장한 다음

  • 첫 번째 파일의 헤더 라인을 인쇄합니다.
  • 2번째 줄부터 모든 파일의 내용과 sort고유 옵션을 사용하여 결과를 출력합니다.
  • 출력을 파일로 리디렉션
files=( *test*.csv )
{
  head -n1 "${files[0]}"
  for i in "${files[@]}"; do
    tail -n+2 "$i"
  done | sort -u
} > output

답변2

NR>1모든 파일을 먼저 사용하고 연결하는 것에 의존할 수는 없습니다 . cat {} +
이와 같이 가능한 한 코드를 재사용하려고 합니다.

{ 
    awk 'NR==1{print;exit}' *test*file*csv
    find . -type f -name '*test*file.csv' -exec awk 'NR>1' {} \; |
    sort -u
} > output.file

결과물 파일

ID,NAME,LOCATION
1,Vikrant,Gurgaon
22,abcd,Noida
2,Bharat,Noida
33,xyz,Hyderabad
3,Raju,Hyderabad

찾기 -exec {} +

-exec 명령 {} +
-exec 작업의 이 변형은 선택한 파일에 대해 지정된 명령을 실행하지만 명령줄은 선택한 각 파일 이름을 끝에 추가하여 구성됩니다.

그래서 직렬로 연결했어요

답변3

다음을 수행하세요.

find . -type f -name '*test*file.csv' -exec awk '!seen[$0]++' {} +

awk가 읽는 각 줄에 대해 이전에 (!) 라는 연관 배열에 설정되지 않은 경우배열에 추가되고 조건이 "true"로 확인되므로 해당 행이 출력됩니다. awk가 동일한 행을 읽으면 조건이 "false"가 되어 중복을 건너뜁니다.

awk에서는 $0전체 행을 의미합니다. 여기서는 이를 배열 키로 사용하고 모든 키(행)를 읽을 때마다 값이 증가합니다. 행의 경우 배열에 설정되지 않은 경우 값은 0이고 인쇄되며, 키 값이 0보다 크면 건너뜁니다.

답변4

명령줄을 약간 수정하면 원하는 결과를 얻을 수 있습니다.

awk 'NR<2||FNR>1' ./*test_file*.csv > temp ;
( head -n 1; sort -u; ) < temp > output.file

결과는 output.file 파일에 있습니다.

관련 정보