![Bash 스크립트 오류입니다. 문자열 경로에 공백과 와일드카드가 포함되어 있습니다.](https://linux55.com/image/56092/Bash%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%20%EC%98%A4%EB%A5%98%EC%9E%85%EB%8B%88%EB%8B%A4.%20%EB%AC%B8%EC%9E%90%EC%97%B4%20%EA%B2%BD%EB%A1%9C%EC%97%90%20%EA%B3%B5%EB%B0%B1%EA%B3%BC%20%EC%99%80%EC%9D%BC%EB%93%9C%EC%B9%B4%EB%93%9C%EA%B0%80%20%ED%8F%AC%ED%95%A8%EB%90%98%EC%96%B4%20%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4..png)
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")