development

재귀 적으로 특정 확장자를 가진 파일을 찾습니다

big-blog 2020. 2. 23. 11:57
반응형

재귀 적으로 특정 확장자를 가진 파일을 찾습니다


내 bash (Latest Ubuntu LTS Release)를 사용하여 디렉토리 및 하위 디렉토리에서 특정 확장자를 가진 모든 파일을 찾으려고합니다.

이것은 스크립트 파일로 작성된 것입니다 :

#!/bin/bash

directory="/home/flip/Desktop"
suffix="in"

browsefolders ()
  for i in "$1"/*; 
  do
    echo "dir :$directory"
    echo "filename: $i"
    #   echo ${i#*.}
    extension=`echo "$i" | cut -d'.' -f2`
    echo "Erweiterung $extension"
    if     [ -f "$i" ]; then        

        if [ $extension == $suffix ]; then
            echo "$i ends with $in"

        else
            echo "$i does NOT end with $in"
        fi
    elif [ -d "$i" ]; then  
    browsefolders "$i"
    fi
  done
}
browsefolders  "$directory"

불행히도 터미널 에서이 스크립트를 시작하면 다음과 같이 말합니다.

[: 29: in: unexpected operator

( $extension대신 'in')

여기서 무슨 일이 일어나고 있습니까, 오류는 어디에 있습니까? 그러나이 중괄호


find $directory -type f -name "*.in"

전체보다 약간 짧습니다 (파일 이름 및 디렉토리 이름의 공백을 처리하는 것이 안전합니다).

.이름에 이름 이없는 항목이 $extension비어 있으면 스크립트가 실패했을 수 있습니다 .


find {directory} -type f -name '*.extension'

현재 디렉토리 및 해당 서브 디렉토리에서 모든 csv 파일을 찾는 예제

find . -type f -name '*.csv'

내가 사용하는 구문은 @Matt가 제안한 것과 약간 다릅니다.

find $directory -type f -name \*.in

(키 스트로크가 적습니다).


사용하지 않고 find:

du -a $directory | awk '{print $2}' | grep '\.in$'

  1. 있다 {빠진 후에는browsefolders ()
  2. 모든 $in해야$suffix
  3. 라인은 cut의 중간 부분 만 표시합니다 front.middle.extension. 쉘 매뉴얼 ${varname%%pattern}과 친구들을 읽으십시오 .

쉘 스크립팅의 연습으로이 작업을 수행한다고 가정합니다 find.

스크립트를 실행하지 않고 적절한 쉘 구문을 확인하려면을 사용하십시오 sh -n scriptname.


pom.xml현재 디렉토리에서 모든 파일 을 찾아서 인쇄하려면 다음을 사용하십시오.

find . -name 'pom.xml' -print

find여기서 명령을 사용하는 것이 유용 할 수 있지만 셸 자체는 타사 도구없이이 요구 사항을 충족하는 옵션을 제공합니다. bash쉘은 순환 경로에서 파일 이름을 얻을 수 있습니다 사용하여 확장 글로브 지원 옵션을 제공합니다 당신이 원하는 확장과 일치합니다.

확장 옵션은 다음과 같은 옵션을 extglob사용하여 설정해야 shopt합니다. 옵션은 지원으로 활성화 -s되고 he -u플래그로 비활성화됩니다 . 또한 몇 가지 옵션을 더 사용할 수 있습니다. 즉 nullglob, 일치하지 않는 glob가 완전히 쓸어 버리고 0 단어로 대체됩니다. 그리고 globstar그것은 모든 디렉토리를 통해 재귀를 허용합니다

shopt -s extglob nullglob globstar

이제 당신이해야 할 일은 glob 표현을 형성하여 아래와 같이 할 수있는 특정 확장자의 파일을 포함시키는 것입니다. 올바르게 인용하고 확장하면 특수 문자가 포함 된 파일 이름이 그대로 유지되고 셸에서 단어 분리로 인해 끊어지지 않기 때문에 배열을 사용하여 glob 결과를 채 웁니다.

예를 들어 *.csv재귀 경로의 모든 파일 을 나열하려면

fileList=(**/*.csv)

옵션 **은 하위 폴더를 통해 재귀를 수행하고 *.csv언급 된 확장명 파일을 포함하도록 확장됩니다. 이제 실제 파일을 인쇄하려면 다음을 수행하십시오.

printf '%s\n' "${fileList[@]}"

쉘 스크립트에서 배열을 사용하고 적절한 인용 확장을 사용하는 것이 올바른 방법이지만 대화식으로 사용하려면 다음 ls과 같이 glob 표현식을 사용 하면됩니다.

ls -1 -- **/*.csv

이것은 여러 파일, 즉 여러 확장자로 끝나는 파일 (즉, find명령에 여러 플래그를 추가하는 것과 유사)과 일치하도록 확장 될 수 있습니다 . 예를 들어 모든 재귀 이미지 파일을받을 필요의 경우를 생각해 확장 즉 *.gif, *.png그리고 *.jpg모든 당신은 필요

ls -1 -- **/+(*.jpg|*.gif|*.png)

이것은 부정적 결과를 갖도록 확장 될 수있다. 동일한 구문으로 glob의 결과를 사용하여 특정 유형의 파일을 제외 할 수 있습니다. 위의 확장자를 가진 파일 이름을 제외하고 싶다고 가정하면 할 수 있습니다

excludeResults=()
excludeResults=(**/!(*.jpg|*.gif|*.png))
printf '%s\n' "${excludeResults[@]}"

이 구문 !()은 내부에 나열된 파일 확장자를 포함하지 않는 부정 연산이며 |확장 정규식 라이브러리에서 globs의 OR 일치를 수행하는 데 사용되는 것과 같은 대체 연산자입니다.

이러한 확장 글로브 지원은 POSIX bourne 쉘에서 사용할 수 없으며 최신 버전에만 적용됩니다 bash. 따라서 POSIX 및 bash셸에서 실행되는 스크립트의 이식성을 고려하고 있다면 이 옵션이 적합하지 않습니다.


find "$PWD" -type f -name "*.in"

find $directory -type f -name "*.in"|grep $substring

for file in "${LOCATION_VAR}"/*.zip
do
  echo "$file"
done 

참고 URL : https://stackoverflow.com/questions/5927369/recursively-look-for-files-with-a-specific-extension



반응형