공백이 포함된 경로의 전역 일치 수를 어떻게 쉽게 계산할 수 있나요?

공백이 포함된 경로의 전역 일치 수를 어떻게 쉽게 계산할 수 있나요?

저는 공백이 있는 경로를 다루고 있습니다.

나는 이런 식으로 글로빙을 수행합니다(두 번째 줄이 글로빙을 설정합니다):

IFS=$'\n'

VAR="$1/"name_*

for file in $VAR; do
  echo $file
  grep ITEM "$file" | wc -l
done

여기서 설정한 값을 사용 하면 파일 이름의 공백으로 인해 오류가 발생하는 것을 방지할 수 있으므로 파일을 올바르게 볼 수 name_*있습니다 $1.IFSfor

그러나 이제는 glob과 일치하는 파일의 총 개수를 얻는 간단한 방법이 필요합니다. for 루프에서 카운터를 사용할 수 있다는 것을 알고 있지만 파이프를 사용하여 이 작업을 수행할 수 있었으면 좋겠습니다 VAR.

그러나 echo $VAR글로빙을 성공적으로 수행했지만 다른 경로가 공백으로 연결되어 있으면 더 이상 항목을 분리할 수 없기 때문에 문제가 발생합니다... IFS 작동 방식과 같이 이 동작을 재정의할 수 있는 방법이 있습니까 for?

답변1

원하는 것이 구분된 값의 목록인 경우 문자열 사용/확장을 피해야 합니다.

기본적인 해결책은 위치 매개변수를 설정하는 것입니다.

set -- "$1"/name_*

공백이나 개행 문자(또는 대부분의 다른 문자)가 있더라도 일치하는 각 파일을 별도의 위치 인수로 유지합니다.

shopt -s failglobbash에서는 glob()이 어떤 파일과도 일치하지 않거나 glob이 어떤 파일과도 일치할 수 없고 어떤 결과도 얻고 싶지 않은 경우(그러나 glob 자체는 아님) 스크립트가 중지되도록 설정해야 합니다 . 스크립트가 중지되지 않도록 하려면 FAILGlob을 설정하지 않은 상태로 두세요.*shopt -s nullglob"$1"/name_*

파일 수(glob에 대한 일치 수를 계산합니다.) 이제 간단하게:

echo "$#"

위치 매개변수의 수입니다.

for 루프는 다음과 같이 줄어듭니다.

for file
do  echo "$file"
done

이렇게 하면 완전히 분할되는 문제가 방지됩니다 IFS.

$1코드 삽입을 방지하려면 외부 값을 인용해야 합니다.
echo "$file"인용되어야 한다.

배열에 목록을 할당하는 것도 가능합니다:

files=( "$1"/name_* )

이렇게 하면 위치 매개변수가 깨지는 것을 방지할 수 있지만 구문이 더 복잡해집니다. 배열의 요소 수는 다음과 같습니다.

echo "${#files[@]}"

루프에는 몇 가지 변경이 필요합니다.

for file in "${files[@]}"; do
    echo "$file"
done

답변2

공간 문제를 해결할 수 있습니다.그리고배열 사용으로 전환하면 개수를 가져옵니다.

VAR=("$1/"name_*) # make array of filenames matching glob

echo "${#VAR[@]}" # number of elements in array

for file in "${VAR[@]}"; do  # loop over individual elements of array
  echo "$file"
  grep ITEM "$file" -c  # grep can count, wc isn't needed
done

관련 정보