공백과 와일드 카드가있는 경로가있는 문자열의 배쉬 스크립트 오류


25

Bash 스크립팅의 기본 사항을 얻는 데 문제가 있습니다. 여기까지 내가 가진 것입니다 :

#!/bin/bash
FILES="/home/john/my directory/*.txt"

for f in "${FILES}"
do
  echo "${f}"
done

내가하고 싶은 것은 모든 .txt파일을 for루프로 나열 하여 그들과 함께 할 수 있습니다. 그러나 공간 my directory과 별표 의 공간 *.txt은 잘 재생되지 않습니다. 변수 이름에 중괄호를 사용하거나 사용하지 않고 큰 따옴표를 사용하거나 사용하지 않고 사용했지만 여전히 모든 .txt파일을 인쇄 할 수는 없습니다 .

이것은 매우 기본적인 일이지만 피곤하고 똑바로 생각할 수 없기 때문에 여전히 어려움을 겪고 있습니다.

내가 무엇을 잘못하고 있지?

내 파일에 공백이나 별표가 없으면 위의 스크립트를 성공적으로 적용 할 수있었습니다 ... 큰 따옴표와 중괄호를 사용하거나 사용하지 않고 실험해야 작동합니다. 그러나 공간과 별표가 모두있는 순간 모든 것이 엉망이됩니다.

답변:


33

따옴표 안에는 *파일 목록으로 확장되지 않습니다. 이러한 와일드 카드를 성공적으로 사용하려면 따옴표 외부에 있어야합니다.

와일드 카드가 확장 되더라도 표현식 "${FILES}"은 파일 목록이 아닌 단일 문자열로 나타납니다.

작동하는 한 가지 방법은 다음과 같습니다.

#!/bin/bash
DIR="/home/john/my directory/"
for f in "$DIR"/*.txt
do
  echo "${f}"
done

위의 공백이나 다른 어려운 문자가있는 파일 이름은 올바르게 처리됩니다.

보다 고급 접근 방식은 bash 배열을 사용할 수 있습니다.

#!/bin/bash
FILES=("/home/john/my directory/"*.txt)
for f in "${FILES[@]}"
do
  echo "${f}"
done

이 경우 FILES파일 이름의 배열입니다. 정의를 둘러싼 parens는 그것을 배열로 만듭니다. (가) 있습니다 *따옴표 밖에서이다. 구조 "${FILES[@]}"는 특별한 경우입니다. 각 문자열이 파일 이름 중 하나 인 문자열 목록으로 확장됩니다. 공백이나 다른 어려운 문자가 포함 된 파일 이름은 올바르게 처리됩니다.


1
훌륭했습니다
John

함수를 통해 이와 같은 경로를 전달하는 경우 변수 큰 문자열의 일부로 연결하지 않고 자체적으로 인용해야 합니다. for f in "$DIR"/*.txt= fine for f in "$DIR/*.txt"= breaks
pospi

7

John1024에 의해 표시된 것과 같이 배열을 사용하는 것이 훨씬 더 의미가 있지만 여기서는 split + glob 연산자를 사용할 수도 있습니다 (스칼라 변수를 따옴표로 묶지 않음).

해당 연산자의 glob 부분 만 원하므로 split 부분 을 비활성화해야합니다 .

#! /bin/sh -
# that also works in any sh, so you don't even need to have or use bash

file_pattern="/home/john/my directory/*.txt"
# all uppercase variables should be reserved for environment variables

IFS='' # disable splitting

for f in $file_pattern # here we're not quoting the variable so
                       # we're invoking the split+glob operator.
do
  printf '%s\n' "$f" # avoid the non-reliable, non-portable "echo"
done

0

와일드 카드 문자 만 따옴표 밖에 두는 것이 가능합니다.
같은 뭔가 :
A의 "공백이있는 파일"에 * ". TXT는"
않습니다
된 처리
완료
와일드 카드 자체가 공간으로 확장하면, 당신은 사용 LS 산전의 목록을 생성 -l처럼 t는, 라인 접근 방식에 따라 파일을 사용해야합니다 bash read를 사용하여 각 파일을 가져옵니다.


-1

당신이 파일의 설정에 처리 할 때, 당신은 그래서 이전과 같은 프로세스를 시작, 자신의 이름에 공백이나 다른 풍경 코드가있을 것입니다 수 있습니다, 고려 for loop또는 find command을 설정 IFS bash env variable하려면 :

IFS=$(echo -en "\n\b")
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.