경로가 아닌 파일 이름을 나열하기 위해 find 명령을 사용하는 방법은 무엇입니까?
온라인에서 몇 가지 답변을 확인했지만 -name
명령에 매개 변수 가 있으면 작동하지 않습니다 (확실하지 않은 일을 잘못하고있을 수 있음). 내가 뭘하려는 것이 유일한 파일 이름 (안 디렉토리 / 경로) 목록에, 그리고 내가 사용 결과를 필터링해야하므로 더 복잡하게, 나는, 다른 확장자를 가진 같은 파일 이름을 가지고 -name
와 -o
, 문제는 제안 즉 I 톱 사용하거나 -printf
또는 basename
이있을 때, 그 잘 작동하지 않습니다 -name *.txt -o name *.pdf
. 이 문제를 해결할 다른 방법이 있습니까?
내 파일의 예 :
/dir1/dir2/dir3/dir4/
/file1.txt
/file1.pdf
/file1.ods ...etc.
목록 당 하나 이상의 파일 유형을 나열하는 데만 관심이 있습니다 ( -name
내 결과를 필터링 하는 데 사용) .
하나의 find
명령 만 사용하여 수행 할 수 있습니까? 아니면 2 단계로 수행해야합니까 (결과를 임시 파일에 저장 한 다음 임시 파일에서 디렉터리를 필터링 / 스트립)? 내가 달성하려는 결과는 한 줄에 파일 이름이있는 텍스트 파일입니다.
file1.txt
file1.pdf
file1.ods
file2.txt
file2.pdf
etc.
내가 사용한 명령은
find /dir1/dir2/dir3/dir4/ -type f -name '*.txt' -o -name '*.pdf' -o -name '*.ods' -printf "%f\n"
GNU find를 사용하고 있습니다.
최신 정보
\(...\)
αғsнιη에 의해 상기 된대로 내가 넣어야한다는 것이 밝혀 졌습니다.
답변
논리 OR 모드에서 여러 표현식을 사용할 때 -o
모두으로 묶어야합니다 \( ... \)
. 그렇지 않으면 마지막 표현식 결과가 항상 적용됩니다. 그리고 -printf '%f\n'
선행 디렉토리가 제거 된 상태에서만 파일 이름을 인쇄하는 데 사용됩니다.
find . -type f \( -name '*.pdf' -o -name '*.txt' \) -printf '%f\n'
볼 man find에서 연산자 에 대한 섹션 ( expr )
:
운영자
...(expr)
우선 순위를 적용합니다. 괄호는 쉘에 대해 특별하므로 일반적으로 인용해야합니다.
따라서 \( ... \)
또는 '(' ... ')'
(괄호 앞뒤의 공백이 중요 함)을 사용하여 이스케이프 할 수 있습니다.
이미 언급했듯이 -name
테스트를 괄호로 묶어야합니다. 이러한 괄호 \( ... \)
는 예 '(' ... ')'
를 들어 쉘로부터 보호하기 위해 (그렇지 않으면 서브 쉘을 지정하는) 것처럼 이스케이프 되거나 인용 되어야 합니다.
standard를 사용 find
하고 파일 이름 접미사 처리를 약간 더 쉽게 만듭니다.
set -- txt pdf ods
for suffix do
set -- "$@" -o -name "*.$suffix"
shift
done
shift
find /dir1/dir2/dir3/dir4 \( "$@" \) -type f -exec basename {} \;
이것은 먼저 위치 매개 변수를 우리가보고자하는 파일 이름 접미사 목록으로 설정하고 (스크립트 인 경우 명령 줄에서도 가져올 수 있음) -name
테스트 의 OR 목록을 구성 합니다. 그런 다음 find
명령 줄 에서 사용됩니다 .
그런 다음 find
명령 자체는 basename
발견 된 각 이름에 대한 유틸리티를 호출합니다 .
대안으로 매개 변수 대체를 사용하여 각 경로 이름의 파일 이름 구성 요소를 제외한 모든 항목을 제거 할 수 있지만 이렇게하려면 경로 이름을 인라인 sh -c
스크립트에 전달해야합니다 .
# [...] as before [...]
find /dir1/dir2/dir3/dir4 \( "$@" \) -type f -exec sh -c '
for pathname do
printf "%s\n" "${pathname##*/}"
done' sh {} +
coreutils의 basename
GNU basename
를 사용하면 다음과 같이 사용 -a
하거나 --multiple
좋아할 수 있지만 적어도 처리 할 파일 이름이 많은 경우를 사용하는 변형보다 더 빨리 실행될 것으로 예상합니다 .
find /dir1/dir2/dir3/dir4 \( "$@" \) -type f -exec basename -a {} +
이것은 basename
가능한 한 몇 번 호출 합니다. 그러나 다시 말하지만, coreutils가 설치되어 있다면 GNU와 함께 findutils도 가질 find
수 -printf '%f\n'
있으며 동일한 작업을 수행하는 데 사용할 수 있습니다 .