Unix의 열 값을 기준으로 특정 정렬 순서로 File1, File2의 행을 File3에 추가합니다.

Unix의 열 값을 기준으로 특정 정렬 순서로 File1, File2의 행을 File3에 추가합니다.

일주일 동안 온라인으로 검색했지만 내 시나리오에 맞는 솔루션을 찾을 수 없는 것 같습니다. 두 개의 파일이 있습니다.

File1에는 많은 열이 포함되어 있지만 마지막 열은 참조 번호입니다. 드라이버 파일로 사용됩니다.

파일 1의 내용:

file1abc|file1abc|file1123|9999999    
file1def|file1def|file1456|8888888

File2에도 많은 열이 포함되어 있지만 참조 번호가 중복되고 필수 정렬 필드가 있습니다.

파일 2 콘텐츠

file2xyz|file2xyz|file2987|sort1|9999999
file2qrs|file2qrs|file2765|sort2|8888888
file2efg|file2efg|file2555|sort3|9999999
file2tuv|file2tuv|file2666|sort2|9999999
file2xyz|file2xyz|file2987|sort1|8888888

원하는 결과를 출력합니다.

파일 1 라인이 첫 번째 라인이 되고, 그 뒤에 참조 번호가 일치하고 # 열을 기준으로 정렬되는 파일 2 라인이 옵니다.

출력에는 다음이 포함됩니다.

file1abc|file1abc|file1123|9999999
file2xyz|file2xyz|file2987|sort1|9999999
file2efg|file2efg|file2555|sort2|9999999
file2tuv|file2tuv|file2666|sort3|9999999
file1def|file1def|file1456|8888888
file2qrs|file2qrs|file2765|sort1|8888888
file2xyz|file2xyz|file2987|sort2|8888888

어떤 도움이나 조언이라도 대단히 감사하겠습니다.

답변1

최신 버전의 GNU awk가 있는 경우 2D 배열을 사용하고 PROCINFO전역적으로 배열 순회를 설정하여 사용하세요.스테르ing(즉, 어휘) 값산업전에오름차순종료 순서:

gawk '
  BEGIN {FS = "|"; PROCINFO["sorted_in"] = "@ind_str_asc"} 
  NR==FNR {a[$NF][$(NF-1)] = $0; next} 
  {print; for(i in a[$NF]) print a[$NF][i]}
' File2 File1
file1abc|file1abc|file1123|9999999
file2xyz|file2xyz|file2987|sort1|9999999
file2tuv|file2tuv|file2666|sort2|9999999
file2efg|file2efg|file2555|sort3|9999999
file1def|file1def|file1456|8888888
file2xyz|file2xyz|file2987|sort1|8888888
file2qrs|file2qrs|file2765|sort2|8888888

이전 GNU awk의 경우 다음 asorti을 사용하여 동일한 결과를 얻을 수 있습니다.

gawk '
  BEGIN{FS="|"} 
  NR==FNR {a[$NF][$(NF-1)] = $0; next} 
  {print; n = asorti(a[$NF],dst,"@ind_str_asc"); for(i=1;i<=n;i++) print a[$NF][dst[i]]}
' File2 File1

정렬하고 싶다면수치적으로(NF-1)번째 필드의 일부 하위 문자열을 기반으로 @ind_str_asc두 번째 배열 인덱스로 변경 @ind_num_asc하고 이를 $(NF-1)적절하게 전처리된 값으로 바꿀 수 있습니다.

substr($(NF-1),5)

또는 정규식을 사용하세요(더 복잡한 키 추출을 위해)

gensub(/[^0-9]*([0-9]+)$/,"\\1","1",$(NF-1))

다른 awk의 경우 1D 배열 및 외부 정렬을 사용할 수 있습니다.

mawk '
  BEGIN {FS="|"; cmd = "sort -t \| -k4"}
  NR==FNR {a[$NF] = a[$NF] (a[$NF]=="" ? "" : ORS) $0; next}
  {print; print a[$NF] | cmd; close(cmd)}' File2 File1
file1abc|file1abc|file1123|9999999
file2xyz|file2xyz|file2987|sort1|9999999
file2tuv|file2tuv|file2666|sort2|9999999
file2efg|file2efg|file2555|sort3|9999999
file1def|file1def|file1456|8888888
file2xyz|file2xyz|file2987|sort1|8888888
file2qrs|file2qrs|file2765|sort2|8888888

여기에서 정렬 옵션은 외부 기능에서 지원하는 옵션으로 제한됩니다 sort. cmd = "sort -t \| -k4.5,4n"4번째 필드의 5번째 문자를 기준으로 숫자순으로 정렬합니다.

관련 정보