쉘 스크립트 정렬

쉘 스크립트 정렬

작은 파일을 정렬하려고 하는데 일부 항목에 두 단어가 포함되어 있지만 하나의 항목으로 정렬하고 싶습니다.

예를 들어 다음과 같은 작은 목록을 고려해보세요.

 peter barker painter
 carl baker cook
 joshua carpenter

이름과 직업입니다. 이제 sort를 사용하여 이러한 항목을 정렬하고 싶다고 가정해 보겠습니다.

문제는 sort가 공백을 필드로 사용한다는 것입니다. 따라서 sort -k 1n을 사용하면 이름별로 정렬됩니다.

하지만 전체 이름을 기준으로 정렬하고 선택적으로 직업을 기준으로 정렬하고 싶습니다. 보시다시피 일부 앙상블에는 이름이 없지만 Joshua는 이름과 직업만 있습니다. 따라서 그 사람의 경우 저는 이름순으로 정렬하고 싶지만 다른 사람의 이름은 모두 이름순으로 정렬하고 싶습니다.

이것이 달성될 수 있습니까?

답변1

성만 누락되고(이름은 제외) 파일의 단어에 공백이 포함되어 있지 않다고 가정합니다.극도로난이도) 먼저 데이터를 탭으로 구분된 형식으로 변환하고 누락된 성을 빈 필드로 바꿉니다.

$ awk -v OFS='\t' 'NF == 3 { $1 = $1 } NF == 2 { $3 = $2; $2 = "" } { print }' <file
peter   barker  painter
carl    baker   cook
joshua          carpenter

스크립트 awk는 2개 또는 3개의 필드가 포함된 행을 감지합니다. 이미 3개의 필드가 있는 행을 탭으로 구분된 3개의 필드로 다시 형식화하는 동시에 원래 2개의 필드만 포함했던 행의 두 번째 필드를 세 번째 필드로 이동합니다.

그런 다음 탭을 구분 기호로 사용하여 데이터를 정렬합니다.

$ awk -v OFS='\t' 'NF == 3 { $1 = $1 } NF == 2 { $3 = $2; $2 = "" } { print }' <file | sort -t $'\t' -k1,2 -k3
carl    baker   cook
joshua          carpenter
peter   barker  painter

여기에서는 이름(필드 1과 필드 2)을 기준으로 정렬한 다음 직업을 기준으로 정렬합니다. bash탭 과 같은 쉘을 사용한다고 가정합니다 $'\t'.


탭 문자(여기서는 :)를 데이터를 방해하지 않는 다른 문자로 바꿀 수 있습니다.

$ awk -v OFS=':' 'NF == 3 { $1 = $1 } NF == 2 { $3 = $2; $2 = "" } { print }' <file | sort -t ':' -k1,2 -k3
carl:baker:cook
joshua::carpenter
peter:barker:painter

tr그런 다음 결과를 전달하여 선택한 구분 기호(여기서는 보기에 좋으므로 탭으로 대체)를 바꿉니다 .

$ awk -v OFS=':' 'NF == 3 { $1 = $1 } NF == 2 { $3 = $2; $2 = "" } { print }' <file | sort -t ':' -k1,2 -k3 | tr ':' '\t'
carl    baker   cook
joshua          carpenter
peter   barker  painter

관련 정보