논리를 기반으로 텍스트 파일 정렬

논리를 기반으로 텍스트 파일 정렬

한 줄에 1000개의 문자열이 포함된 .txt 파일이 있고 파일에 수백만 줄이 있습니다. 클라이언트의 새로운 요구 사항은 다음 논리에 따라 파일을 정렬하는 것입니다. 미리 감사드립니다. 저는 유닉스를 처음 접했고 포럼에서 해결책을 찾을 수 없습니다.

문자 위치 6~11이 "CIP002"인 경우 문자 위치 13~21에 따라 정렬됩니다. 문자 위치 6~11이 "CIP003"인 경우 위치 20~28의 문자에 따라 정렬됩니다.

정렬하기 전에

00001CIP002_123456789ABCDEFJ
00002CIP002_123456790EFGHIJK
87654CIP003_ABCDEFJ123456789
87655CIP003_EFGHIJK123456790

정렬 후

00001CIP002_123456789ABCDEFJ
87654CIP003_ABCDEFJ123456789
00002CIP002_123456790EFGHIJK
87655CIP003_EFGHIJK123456790

답변1

매우 간단합니다. python/awk/perl/bash/whatever를 사용하여 CIP{2,3} 비즈니스 로직을 코딩하고 파이프라인을 구성하세요.

다음과 같은 출력 스트림이 필요합니다.

$ cat two_column.txt
123456789 00001CIP002_123456789ABCDEFJ
123456790 00002CIP002_123456790EFGHIJK
123456789 87654CIP003_ABCDEFJ123456789
123456790 87655CIP003_EFGHIJK123456790

이제 일반적인 방법으로 정렬하고 후처리 단계에서 이 접두사를 제거합니다.

$ cat two_column.txt | sort | awk '{print $2}'  > result.txt

답변2

awk구조하러 오세요 ;)

gawk '$1 ~ /.{5}CIP002_.*/ {print substr($0, 13, 9)" "$0}
$1 ~ /.{5}CIP003_.*/ {print substr($0, 20, 9)" "$0}' before.txt | sort | awk '{print $2}'

그것은 함께 있어야합니다gawk

설명하다:

  • gawk '$1 ~ /.{5}CIP002_.*/ {print substr($0, 13, 9)" "$0} $1 ~ /.{5}CIP003_.*/ {print substr($0, 20, 9)" "$0}' yourfile.txt
    • $1 ~ /.{5}CIP002_.*/필터는 다음을 준수합니다 CIP002.
      • .{5}처음 5개 문자와 일치합니다.
      • 이어서CIP002_
      • 그 뒤에 임의의 문자열이 옵니다.
    • print substr($0, 13, 9)" "$0데이터의 정렬된 부분을 첫 번째 열에 인쇄하는 것입니다.
      • substr($0, 13, 9)문자 13에서 문자 21까지 줄 자르기
      • 123456789이 명령어는 첫 번째 열, 공백, 데이터 순으로 인쇄합니다.

출력 샘플:

123456789 00001CIP002_123456789ABCDEFJ
123456790 00002CIP002_123456790EFGHIJK
123456789 87654CIP003_ABCDEFJ123456789
123456790 87655CIP003_EFGHIJK123456790
  • | sort:생성된 출력을 sort첫 번째 열만을 기준으로 정렬하는 명령의 파이프로 리디렉션합니다.

출력 샘플:

123456789 00001CIP002_123456789ABCDEFJ
123456789 87654CIP003_ABCDEFJ123456789
123456790 00002CIP002_123456790EFGHIJK
123456790 87655CIP003_EFGHIJK123456790
  • | awk {print $2}: 열 정렬 없이 데이터만 인쇄

출력 샘플:

00001CIP002_123456789ABCDEFJ
87654CIP003_ABCDEFJ123456789
00002CIP002_123456790EFGHIJK
87655CIP003_EFGHIJK123456790

답변3

두 가지 접근 방식은 다음과 같습니다.

정렬 키를 앞에 추가하고 정렬 후 삭제합니다.

<your-file awk '{
  print substr($0,6,6) == "CIP002" ? substr($0,13,9) : substr($0,20,9), $0}' |
    sort -k1,1 |
    cut -d ' ' -f 2-

또는 정렬 키 앞에 토큰을 삽입하세요.

<your-file perl -pe '
  substr($_, substr($_,5,6) eq "CIP002" ? 12 : 19, 0) = "|"' |
  sort -t '|' -k2,2.9 |
  tr -d '|'

( |입력에서 다른 일이 발생하지 않는다고 가정).

동점은 sort전체 라인을 어휘적으로 비교하는 최종 비교를 통해 해결됩니다.

관련 정보