온라인에서 몇 가지 답변을 확인했지만 명령에 매개변수가 있으면 작동하지 않습니다 -name
(아마 제가 뭔가 잘못하고 있는지 확실하지 않습니다). 내가 원하는 것은 파일 이름(디렉토리/경로가 아님)만 나열하는 것입니다. 더 복잡하게 만들기 위해 파일 이름은 같지만 확장자가 다르기 때문에 및를 -name
사용하여 결과를 필터링 해야 합니다. -o
질문은 내 제안입니다. 또는 -printf
때로는 basename
제대로 작동하지 않을 때도 있습니다 -name *.txt -o name *.pdf
. 이 문제를 해결할 다른 방법이 있나요?
내 파일의 예:
/dir1/dir2/dir3/dir4/
/file1.txt
/file1.pdf
/file1.ods ...etc.
목록당 나열된 하나 이상의 유형의 파일에만 관심이 있습니다( -name
.
단 1개의 명령으로 수행할 수 있습니까? 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нιι가 나에게 상기시켜 주듯이 를 넣어야 한다는 것이 밝혀졌습니다.
답변1
논리적 OR 패턴으로 여러 표현식을 사용하는 경우 -o
해당 표현식을 모두 묶어야 합니다 \( ... \)
. 그렇지 않으면 마지막 표현식 결과가 항상 존중되며 -printf '%f\n'
모든 선행 디렉터리가 제거된 파일 이름만 인쇄하는 데 사용됩니다.
find . -type f \( -name '*.pdf' -o -name '*.txt' \) -printf '%f\n'
바라보다man find
아래에운영자다음 섹션과 관련하여 ( expr )
:
운영자
...(expr)
우선순위를 강제합니다. 괄호는 쉘에 특별하기 때문에 일반적으로 따옴표로 묶어야 합니다.
따라서 \( ... \)
또는 '(' ... ')'
(괄호 앞과 뒤의 공백이 중요함)을 사용하여 이스케이프할 수 있습니다.
답변2
-name
이미 언급했듯이 테스트를 괄호 안에 그룹화 해야 합니다 . 이러한 괄호는 \( ... \)
예를 들어 '(' ... ')'
쉘로부터 보호하기 위해 이스케이프하거나 인용해야 합니다 (그렇지 않으면 하위 쉘을 지정하게 됩니다).
표준을 사용 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 {} +
basename
적어도 처리할 파일 이름이 많은 경우에는 사용된 변형보다 더 빠르게 실행될 것으로 기대합니다 . 하지만 GNU용 coreutils를 사용하면 다음 과 같이 basename
사용할 수 있습니다 .-a
--multiple
find /dir1/dir2/dir3/dir4 \( "$@" \) -type f -exec basename -a {} +
basename
이는 가능한 한 적은 횟수로 호출됩니다 . 그러나 coreutils가 설치되어 있으면 GNU를 사용하여 동일한 작업을 수행하는 데 find
사용할 수 있는 findutils를 설치할 수도 있습니다.-printf '%f\n'