2013-10-07 3 views
3
#!/bin/bash 
outbound=/home/user/outbound/ 
putfile=DATA_FILE_PUT_*.CSV 
cd $outbound 
filecnt=0 
for file in $putfile; do let filecnt=filecnt+1; done 
echo "Filecount: " $filecnt 

아웃 바운드 디렉토리에 파일이있는 경우이 코드가 잘 작동합니다. 아웃 바운드 경로에 파일을 배치 할 수 있으며 putfile 마스크와 일치하는 한 파일은 예상대로 증가합니다.bash : 변수에 와일드 카드가있는 파일 이름

$outbound에 파일이없는 동안 문제가 발생합니다. 거기에 파일이없는 경우 $filecnt은 여전히 ​​1을 반환하지만 거기에 파일이없는 경우 0을 반환하도록하고 있습니다.

나는 간단한 것을 놓치고 있습니까?

답변

3

set -x을 넣어 사용 스크립트 바로 아래에있는 #! 행을 확인하십시오.

일치하는 파일이없는 경우 와일드 카드는 확장되지 않은 상태로 유지되고 루프는 DATA_FILE_PUT_*.CSV 값을 갖는 file으로 한 번 실행됩니다.

변경하려면 nullglob 옵션을 설정하십시오. 이것은 sh가 아닌 bash에서만 작동합니다. putfile 변수는 와일드 카드 패턴이 아닌 파일 이름의 목록을 포함

shopt -s nullglob 
putfile=DATA_FILE_PUT_*.CSV 
for file in $putfile; do let filecnt=filecnt+1; done 

참고. 대신 일치 목록을 변수에 넣는 것이 더 효과적 일 수 있습니다. 이것은 배열 변수가되어야하며, 현재 디렉토리를 먼저 변경해야합니다. 일치하는 파일의 수는 배열의 길이입니다.

#!/bin/bash 
shopt -s nullglob 
outbound=/home/user/outbound/ 
cd "$outbound" 
putfiles=(DATA_FILE_PUT_*.CSV) 
echo "Filecount: " ${#putfiles} 

파일 이름 다음에 공백이 포함이 여러 단어에 걸쳐 분할됩니다 그렇지 않은 경우, 큰 따옴표로 배열의 확장을 보호하기 위해 조심, 파일을 반복해야하는 경우 (그리고 파일 이름이 포함되어있는 경우 와일드 카드 문자는 확장됩니다).

#!/bin/bash 
shopt -s nullglob 
outbound=/home/user/outbound/ 
cd "$outbound" 
putfiles=(DATA_FILE_PUT_*.CSV) 
for file in "${putfiles[@]}"; do 
    echo "Processing $file" 
done 
0

여기에 코드가 필요한 이유가 확실하지 않습니다. 라이너를 따라 가면 일을해야합니다.

ls ${outbound}/${putfile} | wc -l 

또는

find ${outbound} -maxdepth 1 -type f -name "${putfile}" | wc -l 
+0

개행 문자가 포함 된 파일 이름 (일반적으로 발생하지 않지만 견고성 또는 보안 문제 일 수 있음)이있는 경우이 방법이 작동하지 않음에 유의하십시오. – Gilles

+0

@Gilles 귀하의 의견에 감사드립니다. 'ls'는 그런 문제를 일으킬 수 있다고 당신과 동의하십시오. 그러면'wc'가 뒤 따르는'find'를 선호 할 것입니다. 나는'찾기'가 충분히 견고하다고 믿는다.내가 틀렸다면 나를 바로 잡는다. – jkshah

+2

같은 문제이다.'find'는 강력하지만,'wc -l'은 여전히 ​​파일 이름이 아닌 라인을 센다. 당신은'find ... -print0 | tr -dc '\ 0'| wc -c'이지만, bash에서 계산하는 것이 더 쉽습니다. 'find'로부터 세는 것은 원래의 요구 사항에 있지 않은 서브 디렉토리가있을 경우 서브 디렉토리를 가로 질러갑니다. – Gilles

1

당신은 단순히

for file in $(find . -type f -name="$putfile"); do 
    let filecnt=filecnt+1 
done 

또는를 찾을 파일이 처음

for file in $putfile; do 
    if [ -f "$file" ] ; then 
    let filecnt=filecnt+1 
    fi 
done 

존재하는지 테스트 또는 사용하여 파일을 찾을 수 있습니다 (고정)

더 일치가 발견되지 않을 때, 기본적으로 bash는 단어 DATA_FILE_PUT_*.CSV에 와일드 카드 DATA_FILE_PUT_*.CSV을 확장하기 때문에이 동작을 사용하지 않으려면 1. 의 수와 끝까지 때문이다
filecnt=$(find . -type f -name "$putfile" | wc -l); echo $filecnt 
+1

출력이 와일드 카드 패턴 목록으로 취급되기 때문에 파일 이름에 공백이나'\ [? * '중 하나가 포함될 수 있다면이 방법으로'find'의 출력을 파싱하는 것이 효과가 없습니다. 마지막 명령은'let'을 외부 명령으로 실행하려고 시도하기 때문에 전혀 작동하지 않습니다. – Gilles

+0

오류를 지적 해 주셔서 감사합니다. –

관련 문제