일반 조회를 사용한 결과 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
이는 출력이 다음을 기반으로 함을 의미합니다.파일 이름만, 그러나 폴더 정보는 출력의 일부로 유지되어야 합니다.
편집하다: 하위 디렉터리 구조에 여러 수준이 포함될 수 있으므로 예제가 더 복잡해집니다.
답변1
마지막 필드(필드 구분 기호로 간주)를 기준으로 정렬해야 합니다 /
. 아쉽게도 필드 수가 변경될 때( 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를 끝까지 인쇄하고 다시 /
필드 구분 기호로 처리합니다.
답변2
"-printf" 파일을 사용하여 이름과 경로를 출력하고, 이름별로 정렬하고, 마지막 단계에서 이름을 자릅니다. "###"은 자르기를 돕기 위한 표시일 뿐입니다.
find -name "*.txt" -printf "%f###%p\n" | sort -n | sed 's/.*###//'
%f는 파일 이름을 인쇄하고, %p는 전체 경로를 인쇄합니다.
find 명령을 단순화하여 한 줄로 만들었습니다. 물론 이 부분은 그대로 두십시오 ! -path "./build*"
.
답변3
zsh ≥4.3.10에서:
print -l -- **/*.txt~build*(oe\''REPLY=${REPLY:t}'\')
**/*.txt
*.txt
현재 디렉터리 및 해당 하위 디렉터리와 일치합니다 .재귀적으로.~build*
들어오지 못하게 하다build*
텍스트가 (like )로! -path './build*'
시작하는 콘텐츠 와 일치합니다 . (setopt extended_glob
먼저 필요합니다.)(oe\''…'\')
정렬이다글로벌 예선.REPLY=…
반환될 문자열에서 정렬할 문자열을 구성합니다.${REPLY:t}
~이다기본 이름("꼬리") 경로입니다.