하위 디렉토리에서 파일을 찾고 단일 명령으로 파일 이름으로 정렬하는 방법은 무엇입니까? 찾기 결과

다음을 사용하여 일반 찾기 결과 find . ! -path "./build*" -name "*.txt":

./tool/001-sub.txt
./tool/000-main.txt
./zo/001-int.txt
./zo/id/002-and.txt
./as/002-mod.txt

그리고 다음과 sort -n같이 정렬하면 :

./as/002-mod.txt
./tool/000-main.txt
./tool/001-sub.txt
./zo/001-int.txt
./zo/id/002-and.txt

그러나 원하는 출력은 다음과 같습니다.

./tool/000-main.txt
./zo/001-int.txt
./tool/001-sub.txt
./zo/id/002-and.txt
./as/002-mod.txt

즉 , 파일 이름 만 기준으로 출력이 정렬 되지만 폴더 정보는 출력의 일부로 유지되어야합니다.

편집 : 서브 디렉토리 구조에 둘 이상의 레벨이 포함될 수 있으므로 예제를 더 복잡하게 만드십시오.



답변

마지막 필드를 기준으로 정렬해야합니다 ( /필드 구분 기호로 간주 ). 불행히도 필자는 필드 수가 다양 sort -k할 때 (음수 값만 취할 수있는 경우)이 작업을 수행 할 수있는 도구를 생각할 수 없습니다 .

이 문제를 해결하려면 데코레이션-정렬-데코레이션을 수행해야합니다. 즉, 파일 이름을 가져 와서 처음에 필드 구분 기호를 입력 한 다음 정렬하고 첫 번째 열과 필드 구분 기호를 제거하십시오.

find . ! -path "./build*" -name "*.txt" |\
    awk -vFS=/ -vOFS=/ '{ print $NF,$0 }' |\
    sort -n -t / |\
    cut -f2- -d/

awk명령은 필드 구분 기호 FS/; 이것은 필드를 읽는 방식에 영향을줍니다. 출력 필드 분리가 OFS 또한 설정된다 /; 레코드를 인쇄하는 방식에 영향을줍니다. 다음 문장은 마지막 열 ( NF레코드의 필드 수이므로 마지막 필드의 인덱스이기도 함)과 전체 레코드 ( $0전체 레코드 임)를 인쇄합니다. 그들 사이에 OFS가 인쇄됩니다. 그런 다음 필드 구분 기호로 sort취급 되는 목록이 작성 /됩니다. 레코드에 파일 이름이 먼저 있기 때문에 그 순서대로 정렬됩니다. 그런 다음 cut필드 2부터 끝까지 만 필드를 인쇄 /하여 필드 구분 기호로 다시 처리 합니다.


답변

‘-printf’파일을 사용하여 이름과 경로를 출력하고 이름별로 정렬하고 마지막 단계에서 이름을 잘라냅니다. ‘###’은 절단을 돕는 마커입니다.

find -name "*.txt" -printf "%f###%p\n" | sort -n | sed 's/.*###//'

% f는 파일 이름을 인쇄하고, 전체 경로의 % p를 인쇄합니다.

find 명령을 단순화하여 한 줄로 만들었습니다 ! -path "./build*". 물론 부품을 떠날 것 입니다.


답변

zsh ≥4.3.10에서 :

print -l -- **/*.txt~build*(oe\''REPLY=${REPLY:t}'\')
  • **/*.txt*.txt현재 디렉토리 및 해당 서브 디렉토리에서 재귀 적으로 일치 합니다 .
  • ~build* 텍스트가 build*(예 :)로 시작하는 일치 항목을 제외합니다! -path './build*' . ( setopt extended_glob먼저 필요합니다 .)
  • (oe\''…'\')정렬 glob 한정자 입니다. REPLY=…반환 할 문자열에서 정렬 할 문자열을 구성합니다.
  • ${REPLY:t}경로 의 기본 이름 ( “꼬리”)입니다.