null로 끝나는 파일 경로를 동일한 출력에 두 번 파이프하지만 두 번째는 기본 이름으로 정렬됩니다.

null로 끝나는 파일 경로를 동일한 출력에 두 번 파이프하지만 두 번째는 기본 이름으로 정렬됩니다.

따라서 null로 끝나는 파일 이름으로 경로를 인쇄하는 스크립트가 있다고 가정해 보겠습니다 find.

또한 각 경로가 기본 이름별로 정렬된 다른 버전의 출력을 인쇄하고 싶습니다. 다시 실행 하지 않고 이를 달성 find하고 두 출력을 마치 단일 출력인 것처럼 동일한 명령으로 파이프하고 싶습니다.

나는 이것이 Perl을 사용하여 수행될 수 있다고 생각하지만, 나는 그것에 익숙하지 않습니다.

고려해야 할 몇 가지 중요한 사항은 다음과 같습니다.

  1. 초기 출력은 변경되지 않고 실시간으로 전달되어야 합니다. 즉, 첫 번째 실행 중에 명령은 두 번째 명령에 대한 행을 있는 그대로 출력하고 find입력(예: )이 완료되면 정렬을 위해 캡처해야 합니다.

  2. find(또는 0으로 끝나는 경로를 출력하는 다른 프로그램)이 완료된 후 스크립트는 수신된 각 경로를 기본 이름별로 정렬해야 합니다. 정렬 시 경로가 후행 슬래시로 끝나지 않는 한 마지막 문자 /앞의 모든 내용을 무시해야 합니다. 후행 슬래시가 있는 경우 후행 슬래시가 있는 디렉터리가 함께 그룹화되지 않도록 하기 위해 선행하는 필드를 기준으로 정렬해야 합니다. 정렬이 완료되면 원본 출력 후에 정렬된 출력물을 인쇄해야 합니다.

어떻게 하면 쉽게 달성할 수 있나요?

答え1

Perl의 경우 이는 다음과 같습니다:

find . ... -print0 |
  perl -MFile::Basename -0 -lne '
    print; push @files, $_;
    END {
      print $_->[0] for sort {$a->[1] cmp $b->[1]} map {[$_, basename$_]} @files
    }' | ...

그리고:

  • -MFile::Basename uses File::Basename M모듈 의 기능basename()
  • -0: 입력 레코드 구분 기호를 NUL 바이트로 설정합니다.
  • -n: 각 입력 레코드에 대해 xpression을 실행하는 패턴입니다 sed -n.-e
  • -l: 출력 레코드 구분 기호를 입력 레코드 구분 기호(여기서는 NUL)와 동일하게 설정하고 레코드 끝에서 입력 레코드 구분 기호를 제거하여 $_표현식에 레코드 내용을 포함합니다 -e.
  • 각 레코드에 대해 이를 가져와 print(출력 레코드 구분 기호가 뒤에 옴) 목록 push에 넣습니다.@files
  • 에서는 a의 ed 목록을 END반복합니다 .sort슈워츠 변환목록에 있습니다.

関連情報