태그 보관물: recursion

recursion

재귀 적으로 특정 확장자를 가진 파일을 찾습니다 $extension == $suffix ]; then

내 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.


답변

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


답변

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셸에서 실행되는 스크립트의 이식성을 고려하고 있다면 이 옵션이 적합하지 않습니다.