Bash 스크립트 오류입니다. 문자열 경로에 공백과 와일드카드가 포함되어 있습니다.

Bash 스크립트 오류입니다. 문자열 경로에 공백과 와일드카드가 포함되어 있습니다.

Bash 스크립팅의 기본 사항을 이해하는 데 문제가 있습니다. 이것이 내가 지금까지 가지고 있는 것입니다:

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

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

내가 원하는 것은 루프 .txt의 모든 파일을 나열하여 해당 파일로 뭔가를 할 수 있도록 하는 것입니다. for그러나 공백 my directory과 별표는 *.txt서로 잘 작동하지 않습니다. 변수 이름에 큰따옴표를 사용하거나 사용하지 않고 중괄호를 사용하거나 사용하지 않고 사용해 보았지만 여전히 모든 .txt파일을 인쇄할 수 없습니다.

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

내가 뭘 잘못했나요?

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

답변1

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

와일드카드가 확장되더라도 표현식은 "${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파일 이름의 배열입니다. 주위에 괄호를 정의하여 배열로 만듭니다. *따옴표 밖에 있다는 점에 유의하십시오 . 이 구성은 "${FILES[@]}"특별한 경우입니다. 각 문자열이 파일 이름 중 하나인 문자열 목록으로 확장됩니다. 공백이나 기타 어려운 문자가 포함된 파일 이름은 올바르게 처리됩니다.

답변2

John1024에 표시된 대로 배열을 사용하는 것이 더 합리적이지만 여기서는 분할+glob 연산자(따옴표가 없는 스칼라 변수)를 사용할 수도 있습니다.

연산자의 glob 부분만 필요하므로 비활성화해야 합니다.나뉘다부분:

#! /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

답변3

당신이 할 수 있는 일은 와일드카드를 따옴표 밖에 두는 것입니다.
다음과 같습니다:
for a in "files with space"*".txt"
do
process
done
와일드카드 자체가 공백으로 확장되면 한 줄에 하나의 파일 접근 방식을 사용할 필요가 없습니다. 예를 들어 ls -l을 사용하여 목록 파일을 따르고 bash read를 사용하여 각 파일을 가져옵니다.

답변4

파일 세트를 처리하려는 경우 파일 이름에 공백이나 기타 풍경 코드가 포함될 수 있다는 점을 고려하여 처리를 시작하기 전에 예를 들어 다음과 같이 for loop설정 find command합니다 IFS bash env variable.

IFS=$(echo -en "\n\b")

관련 정보