숫자 이름으로 폴더를 반복하는 스크립트

숫자 이름으로 폴더를 반복하는 스크립트

WordPress 폴더의 이미지를 압축하기 위해 bash 스크립트를 작성 중입니다. WordPress 폴더 구조는 다음과 같습니다.

> wp-content/uploads/2014/01/filename.jpg
> wp-content/uploads/2014/02/filename.jpg
> wp-content/uploads/2014/03/filename.jpg
> wp-content/uploads/2014/04/filename.jpg
> 
> i.e. wp-content/uploads/YEAR/MONTH/filename.jpg

업로드 폴더에는 다른 폴더(플러그인 설치 시 생성됨)가 많이 있으므로 숫자 이름이 있는 폴더만 순환한 다음 이미지를 압축해 보았습니다. 이것이 내가 지금까지 가지고 있는 것입니다:

DIR_UPLOADS=/home/html/wp-content/uploads/
cd ${DIR_UPLOADS}    
for d in *; do                 # First level i.e. 2014, 2013 folders.
     regx='^[0-9]+$'           # Regular Expression to check for numerics.
     if [[$d =~ $regx]]; then  # Check if folder name is numeric.
       #echo "error: Not a number" >&2; exit 1
       cd $d
       for z in *; do          # Second level i.e. the months folders 01, 02 etc.
        cd $z
        for x in *; do         # Third level the actual file.              
          echo 'Compress Image'
        done
      done
     fi
    done

숫자 폴더를 감지하기 위해 reg ex를 사용하려고 하는데, 이는 정확하지 않지만 거의 근접한 것 같습니다.

답변1

bash이를 위해 확장된 와일드카드를 사용할 수 있습니다 .

shopt -s extglob
DIR_UPLOADS=/home/html/wp-content/uploads/
cd ${DIR_UPLOADS}

for dir in $PWD/+([0-9])/+([0-9]); do
  cd "$dir" &&
    for file in *; do
      echo 'Compress Image'
    done
done

매뉴얼 페이지에서:

+(pattern-list)
    Matches one or more occurrences of the given patterns

따라서 내부에 숫자 범위를 입력하면 파일/디렉토리가 일치합니다. 조건을 추가하면 &&일치 항목이 디렉터리인 경우에만 이미지를 압축할 수 있습니다(실제로 해당 디렉터리에 성공적으로 입력한 경우).

확장된 와일드카드 없이도 이 작업을 수행할 수 있습니다 [1-2][0-9][0-9][0-9]/[0-1][0-9]. 이는 해당 시점에 이미지가 없더라도 매년/월에 대한 목차를 입력하려고 하지 않기 때문에 중괄호 확장을 시도하는 것보다 낫습니다.

답변2

이 작업을 수행하기 위해 다음 접근 방식을 사용할 것이라고 생각했지만 find스크립팅 질문에 대한 답변을 돕기 위해 예제를 약간 수정했습니다.

#!/bin/bash

for d in *; do                # First level i.e. 2014, 2013 folders.
  regx='^[0-9]+$'             # Regular Expression to check for numerics.
  echo "dir: $d"
  if [[ $d =~ $regx ]]; then  # Check if folder name is numeric.
    echo "found num: $d"
    pushd $d >& /dev/null
    for z in *; do            # Second level i.e. the months folders 01, 02 etc.
      pushd $z >& /dev/null
      for x in *; do          # Third level the actual file.              
        echo "Compressing Image: $x"
      done
      popd >& /dev/null
    done
    popd >& /dev/null
  fi
done

당신의 방법은 좋아 보입니다. 내 생각에 문제의 일부는 cd. 나는 일반적 으로 귀하의 예에 추가했기 때문에 대신 pushd사용 합니다.popd

이제 WordPress 업로드 디렉터리에서 이 명령을 실행하면 다음과 같습니다.

$ pwd
/var/www/html/apps/wordpress/wp-content/uploads

실행 예시:

$ ./asc.bash | head -15
dir: 2009
found num: 2009
Compressing Image: GURULABS-RPM-GUIDE-v1.0.pdf
Compressing Image: How_to_create_an_RPM_package.mht
Compressing Image: ss_mtr_1-150x150.png
Compressing Image: ss_mtr_1-300x146.png
Compressing Image: ss_mtr_1.png
Compressing Image: ss_mtr_2-150x150.png
Compressing Image: ss_mtr_2-300x115.png
Compressing Image: ss_mtr_2.png
Compressing Image: ss_mtr_3-150x150.png
Compressing Image: ss_mtr_3-300x117.png
Compressing Image: ss_mtr_3.png
Compressing Image: ss1_trac_gitplugin-1024x262.png
Compressing Image: ss1_trac_gitplugin-150x150.png

개선하다

특정 달을 보기 전에 해당 달의 디렉터리가 비어 있는 경우를 대비해 몇 가지 테스트를 추가하겠습니다. 그렇지 않으면 다음과 같은 결과를 얻게 됩니다:

Compressing Image: *
Compressing Image: *
Compressing Image: *

이러한 디렉터리 트리를 탐색하는 것은 까다로울 수 있습니다. 디렉토리 구조는 꽤 구조화되어 있으므로 다음과 같이 하면 어떨까요?

for dir in 20*/*; do
  echo "$dir"
  for files in $dir/*; do
    if [ -e $dir/$files ]; then
      echo "$dir/$files: ..compress.."
    fi
  done
done

또는 다음과 같습니다:

for year in $(printf '%4d\n' {2000..2014}); do
  echo "$year"
  for mnth in $(printf '%02d\n' {00..12}); do
    if [ -e $year/$mnth ]; then
      echo "$mnth"
    fi
  done
done

관련 정보