저는 몇 가지 스크립트를 작성하고 있습니다.
for x in `find ./ -name *.pdf`
do
echo pathname $x
done
내 파일 이름은 입니다 Test1 ( Volume II)
.Test2 ( Volume II)
pathname Test1
pathname (
pathname Volume
pathname II
…
어떻게 변수로 유지합니까?
답변1
이 사이트에서 여러 번 언급했듯이 Bourne/POSIX 쉘에서 따옴표가 없는 변수 확장(예: 또는 $var
) 또는 명령 대체(예: 또는 대부분의 쉘에서 산술 확장(예: ) )는 분할+glob 연산 기호입니다.`cmd`
$(cmd)
$((11 * 11))
내용 $var
또는 출력 (후행 개행 없음) 은 특수 변수(기본적으로 SPC, TAB 및 NL 문자(및 의 NUL ) 포함)의 현재 값과 해당 변수에 의해 생성된 각 단어를 cmd
기준으로 분할됩니다 . 파일 이름에 의해 생성됩니다.$IFS
zsh
와일드카드.
예를 들어, find
출력 ./foo bar.pdf\n./*foo*\tbar.pdf\n
( \t
TAB 및 \n
NL을 나타냄)이 기본값 인 경우 명령 대체는 (후행 줄 바꿈 제거)로 확장된 다음 , , 및 로 분할 $IFS
됩니다. 여기서 와일드카드 패턴은 인수 수만큼 확장됩니다. 현재 디렉토리에 있는 것처럼 Exists 이름에는 ../foo bar.pdf\n./*foo*\tbar.pdf
./foo
bar.pdf
./*foo*
foo.pdf
./*foo*
foo
개행 문자로만 분할하려면 $IFS
다음과 같이 개행 문자로만 설정해야 합니다.
IFS='
'
와일드카드 패턴을 확장하지 않으려면 다음을 사용하여 비활성화해야 합니다.
set -f
그러나 줄 바꿈은 파일 이름의 모든 문자만큼 유효하므로 일반적으로 find -print
출력은 안정적으로 사후 처리될 수 없습니다.
출력은 다음과 같습니다.
./a.pdf
./b.pdf
현재 디렉토리의 및 파일을 나타내 거나 디렉토리에서 호출된 파일을 a.pdf
나타냅니다 .b.pdf
b.pdf
a.pdf\n.
GNU (GNU에서 유래) find
와 같은 일부 구현에는 NL 문자 대신 NUL 문자가 뒤에 오는 파일 이름을 출력하는 조건자가 있습니다. 표준을 사용하면 동일한 결과를 얻을 수 있습니다 . NUL은 파일 이름에 나타날 수 없는 유일한 문자입니다.find
-print0
find
-exec printf '%s\0' {} +
그러나 zsh
변수에 NUL 문자(예: 문자)를 저장할 수 있는 유일한 셸이므로 $IFS
다음과 같습니다.
IFS=$'\0'
for i in `find ... -print0`; do
...
done
( 명령 대체 시 와일드카드가 수행되지 않으므로 in은 필요하지 않습니다.) 다른 쉘에서는 작동 하지만 set -f
다른 쉘에서는 작동하지 않습니다.zsh
zsh
zsh
가장 이식 가능한 방법은 find
이러한 파일에서 실행하려는 명령을 호출하는 것입니다. @Gnouc가 제안한 대로:
find . -name '*.pdf' -exec the command {} \;
쉘 문과 관련된 좀 더 복잡한 작업이 필요한 경우에도 다음을 수행할 수 있습니다.
find . -name '*.pdf' -exec sh -c '
for i do
something complex with "$i"
done' sh {} +
zsh
또는 를 사용하여 bash
다음을 수행할 수도 있습니다.
find . -name '*.pdf' -print0 |
while IFS= read -r -d '' file; do
whatever with "$file"
done
그러나 루프 내의 표준 입력은 영향을 받습니다.
zsh
find
(1990년 이후)에는 구문을 통해 와일드카드 기능에 대부분의 기능이 포함되어 있습니다. 여기서는 모든 수준의 하위 디렉터리( (*/)#
문법 또는 더 간단한 형식)와 와일드카드 한정자( **/
위젯에서 , . ..)를 지정할 수 있습니다.-type f
-mtime
-perm
find
그 중 일부는 2003년, 2005년, 2009년, 2010년에 재생산되었습니다 **/
(이 섹션도 재생산되었지만). 그리고 그 중 어느 것도 기본적으로 활성화하지 않습니다. 불행하게도 및 는 디렉토리(예: /in 또는 in or)에 대한 심볼릭 링크를 따릅니다.ksh93
fish
bash
tcsh
tcsh
***/
bash
fish
**
-L
-follow
find
***
zsh
tcsh
이러한 셸에서는 파일에 의존하지 않고 모든 수준의 하위 디렉터리에서 파일을 찾을 수 있지만 위의 경고와 globbing 한정자에만 pdf
주의하세요 .find
fish
bash
zsh
예를 들어 이는 다음 zsh
과 같습니다.
find . -name '*.pdf' -type f -exec ls -ld {} +
할 것이다:
ls -ld ./**/*.pdf(D.)
이를 사용할 때 bash
다음을 수행해야 합니다.
shopt -s failglob
shopt -s globstar
files=(./**/*.pdf) &&
for i do
[ -f "$i" ] && ! [ -L "$i" ] && set -- "$i" "$@"
shift
done && ls -ld "$@"
답변2
가장 안전한 방법은 globbing을 사용하는 것입니다.
for file in *pdf; do echo pathname "$file"; done
모든 PDF를 재귀적으로 찾으려면 다음을 수행하십시오.
shopt -s globstar
for file in **/*pdf; do echo pathname "$file"; done
답변3
다음 줄을 시도해 보세요:
find ./ -name "*.pdf" -exec echo pathname {} \;
답변4
기본 FreeBSD 셸(/bin/sh)에 대한 솔루션을 찾는 데 몇 시간을 보낸 후 마침내 나만의 솔루션을 생각해냈습니다. 공백을 파괴/생성하기 위해 sed를 사용하는 것이 포함됩니다. 또한 while 루프(/bin/sh에 하위 쉘을 생성함)를 사용하는 것과는 달리 루프 내부에서 변수를 변경하고 외부에서 사용할 수도 있습니다.
REMOTE_FOLDER=/media/images
FILE_LIST=$(find $REMOTE_FOLDER | sed 's/ /\/\/\/\//g')
for FILE in $FILE_LIST; do
FILE=$(echo $FILE | sed 's/\/\/\/\// /g')
# do whatever you need to do with $FILE
done