4n줄이 포함된 파일이 있습니다. 다음은 8줄의 내용을 발췌한 것입니다.
6115 8.88443
6116 6.61875
6118 16.5949
6117 19.4129
6116 6.619
6117 16.5979
6118 19.4111
6115 8.88433
내가 하고 싶은 것은 첫 번째 열을 기준으로 각 블록이 4개의 행으로 구성된 블록을 정렬하는 것입니다. 발췌문의 출력은 다음과 같아야 합니다.
6115 8.88443
6116 6.61875
6117 19.4129
6118 16.5949
6115 8.88433
6116 6.619
6117 16.5979
6118 19.4111
답변1
한 가지 옵션은 다음을 사용하는 것입니다.앗N 줄마다 초기 시퀀스 번호 접두사를 추가합니다(귀하의 경우 N=4). 그런 다음 에 기본 정렬 열로 접두사를 입력합니다 sort
.
N=4의 예:
awk '{print int((NR-1)/4), $0}' file.txt | sort -n -k1,1 -k2,2 | cut -f2- -d' '
답변2
이것이 일회성이고 Python, Perl 또는 awk를 배우고 싶지 않다면 기본 split
및 sort
명령을 배울 수 있습니다.
먼저 다음 옵션을 사용하여 파일을 4줄 청크로 분할합니다 -l
.
split -a 6 -l 4 input_file my_prefix_
for fn in my_prefix_*; do
sort -n -o $fn $fn
done
cat my_prefix_* > output_file
rm my_prefix_*
sort -n
첫 번째 열의 값(1234 이전의 999)을 기준으로 정렬합니다. -a 6
26^6*4 라인의 파일을 처리해야 합니다. my_prefix_
사용 중인 디렉토리에 고유한 것이어야 합니다.
답변3
Perl을 사용하여 이 작업을 수행할 수 있습니다.
perl -nle '
push @a,$_;
unless($. % 4){
print join "\n",sort {$a <=> $b} @a; # Sort @a, and print its contents
@a = (); # Empty @a to start a new block
}
' your_file
어떻게 작동하나요?
-n
--> 각 입력 라인에 대해 코드를 실행합니다(그리고 현재 라인을 에 넣습니다$_
).-l
--> 모든 출력에 줄바꿈을 추가합니다.print
-e
--> 다음 문자열을 Perl 코드로 실행- 각 행은 배열에 추가됩니다
@a
. $.
현재 줄 번호를 저장합니다. 줄 번호가 0 모듈로 4와 같지 않으면 작업을 계속합니다. 그 경우예0 모듈로 4와 일치하면 숫자가 4의 배수(블록 끝)인 행에 도달합니다. 이 경우@a
항목을 오름차순으로 정렬하고 줄 바꿈 문자로 연결된 정렬된 배열의 항목을 표준에 인쇄합니다. 산출.
답변4
다음은 "순수한" awk
솔루션입니다.
예제 데이터에 표시된 것처럼 인덱스가 항상 동일한 증가 순서(6115-6119)인 경우 알고리즘 "단축키"를 사용할 수 있습니다.
awk '{a[$1]=$0} !(NR%4){for(i=6115;i<6119;print a[i++]);}'
이것은 실제로
a
인덱스 위치 6115-6119에 분산된 배열에 모든 행을 추가합니다.- 4줄( )마다
!(NR%4)
배열 내용을 반복하여 원하는 순서로 인쇄합니다.
숫자 인덱스가 항상 동일한 4개의 인덱스이지만 증가하는 정수 시퀀스가 아닌 경우 다음과 같이 정렬해야 합니다.
awk '{a[$1]=$0} !(NR%4){asort(a,b); for(i=1;i<5;print b[i++]);}'
참고: 이는 GNU awk용이므로 다른 사용자는 이를 지원하지 않을 수 있습니다 asort
.
4개의 블록이 각각 다른 숫자 ID를 가질 수 있는 경우:
awk '{a[$1]=$0} !(NR%4){asort(a); for(i=1;i<5;print a[i++]); delete a}'
참고: TIL은 다음에서 유래합니다.@Gilles 자체 답변(+2) 이 사용법은 delete
아직 POSIX가 아니지만 일반적으로 지원됩니다..
사용할 올바른™ 버전 delete
:
awk '{a[$1]=$0} !(NR%4){asort(a); for(i=1;i<5;delete a[i++]){print a[i]}}'
더 많은 메모리와 크기를 사용하여 제거되지 않은 버전:
awk '{a[n][$1]=$0} !(NR%4){asort(a[n]); for(i=1;i<5;print a[n][i++]); n++}