bash + 특정 경로 아래의 폴더가 숫자로 끝나는지 확인하는 방법

bash + 특정 경로 아래의 폴더가 숫자로 끝나는지 확인하는 방법

/var/kafka폴더 아래의 모든 폴더가 숫자로 끝나는 지 확인하고 싶습니다 . 그렇지 않으면 오류가 발생하여 종료됩니다.

ls -ltr  /var/kafka
drwxr-xr-x 399 kafka kafka 28672 Nov  9 13:10 data6
drwxr-xr-x 392 kafka kafka 28672 Nov  9 13:10 data5
drwxr-xr-x 391 kafka kafka 28672 Nov  9 13:10 data1
drwxr-xr-x 405 kafka kafka 28672 Nov  9 13:10 data2
drwxr-xr-x 386 kafka kafka 28672 Nov  9 13:10 data4
drwxr-xr-x 389 kafka kafka 28672 Nov  9 13:10 data8
drwxr-xr-x 406 kafka kafka 28672 Nov  9 13:10 data7
drwxr-xr-x 397 kafka kafka 28672 Nov  9 13:10 data3

그래서 다음과 같은 간단한 코드를 만들었습니다(bash 스크립트에 있어야 함).

for i in `  ls -ltr  /var/kafka | awk '{print $NF}' `; do  [[ ! $i  = *?[0-9] ]] && echo "ERROR folder/s not ended with number" && exit 1 ; done

/var/kafka하지만 위의 예제 코드는 너무 길어서 아래 폴더가 숫자로 끝나는 지 간단히 확인하기 위해 다른 우아한 짧은 명령을 찾고 싶습니다.

awk/sed/또는 Perl라이너에도 사용할 수 있습니다 .

답변1

그리고 zsh:

files=( /var/kafka/*[^0-9](ND) )
if (( $#files )); then
  print -rlu2 -- "There are files whose name doesn't end in an ASCII digit:" ' - '$^files
  exit 1
fi

bash같은

shopt -s nullglob dotglob
shopt -u failglob
files=( /var/kafka/*[^0123456789] )
if (( ${#files[@]} )); then
  echo>&2 "There are files whose name doesn't end in an ASCII digit:"
  printf>&2 ' - %s\n' "${files[@]}"
  exit 1
fi

t이러한 파일의 기본 이름만 표시하려면 /ail( foo대신 /var/kafka/foo) 및 를 로 바꾸십시오 $^files.$^files:t"${files[@]}""${files[@]##*/}"

엄밀히 말하면 *[^0-9](또는 *[^0123456789]bash에서) 숫자로 끝나지 않는 파일 이름의 경우 ^*[0-9]zsh(필요) set -o extendedglob또는 !(*[0-9])bash(필요 shopt -s extglob)에서 숫자가 아닌 문자로 끝나는 파일 이름과 일치합니다. 이름은 비워둘 수 없습니다. 이는 동일해야 합니다.

오류 메시지에 파일을 나열할 필요가 없으면 zsh에서 다음과 같이 단축할 수 있습니다.

if () (( $# )) /var/kafka/*[^0-9](NDY1); then
  print -ru2 "There are files whose name doesn't end in an ASCII digit"
  exit 1
fi

첫 번째 일치 항목 보기를 중단 Y1하고 일치 항목 목록을 $#하나 이상의 인수(0이 아닌)가 전달되면 true를 반환하는 익명 함수에 전달합니다.

특정 유형의 파일만 고려해야 하는 경우목차여전히 zsh에서 /glob 한정자에 추가합니다.

dirs=( /var/kafka/*[^0-9](ND/) )
if (( $#dirs )); then
  print -rlu2 -- "There are directories whose name doesn't end in an ASCII digit:" ' - '$^dirs
  exit 1
fi

bash에는 glob 한정자가 없지만 find이름이 숫자로 끝나지 않는 디렉터리 유형 파일을 보고할 수 있습니다.

bash4.4 이상을 사용하고 다음 find을 지원하세요 -print0.

readarray -td '' dirs < <(
  cd /var/kafka &&
    LC_ALL=C find . ! -name . -prune -type d ! -name '*[0-9]' -print0
)
if (( ${#dirs[@]} )); then
  echo>&2 "There are dirs whose name doesn't end in an ASCII digit:"
  printf>&2 ' - %s\n' "${dirs[@]}"
  exit 1
fi

이전 버전의 bash를 사용하면 항상 루프에서 배열을 채울 수 있습니다.

dirs=()
while IFS= read -rd '' dir; do
  dirs=("${dirs[@]}" "$dir")
done < <(
  cd /var/kafka &&
    LC_ALL=C find . ! -name . -prune -type d ! -name '*[0-9]' -print0
)

우리는 다른 로케일에서 종종 0과 9 사이를 정렬하는 수천 개의 다른 문자 대신 0123456789에서만 LC_ALL=C이러한 일치를 사용하고 0개 이상의 문자에서 0개 이상의 바이트와 일치하는 항목 도 만듭니다.[0-9]**[0-9]

이제 일부 로케일은 0123456789 외에 일부 문자가 포함된 문자 인코딩을 사용하며 인코딩은 0123456789와 동일한 바이트 값으로 끝납니다. 예를 들어, 중국에서 사용되는 GB18030 문자 집합에서는 다음과 같습니다.

$ LC_ALL=zh_CN.gb18030 luit
$ locale charmap
GB18030
$ printf %s '¾' | LC_ALL=C od -tx1 -tc
0000000  81  30  86  36
        201   0 206   6
0000004

이 문자 는 분명한 이유로 0에서 9 사이로 정렬되고 GB18030 인코딩은 바이트 0x36으로 끝나기 때문에 일반적 으로 인코딩 방법에 관계없이 ¾일치합니다 . 이는 ASCII 숫자 문자의 인코딩이기도 합니다.[0-9]6

따라서 C 로케일에서는 GB18030 인코딩으로 구성된 파일 경로가 /var/kafka/¾¾¾ASCII 숫자로 끝나는 것으로 처리되어 보고되지 않습니다. 그것이되어야하는지 여부는 또 다른 문제입니다.

답변2

사용 find:

LC_ALL=C find /var/kafka -mindepth 1 -maxdepth 1 -type d -regex '.*[^0-9]$' | grep '^' \
&& echo "Error in folder name"

합리적인 반환 코드를 얻기 위해 "학대"하고 있습니다. grep더 나은 방법을 아는 사람이 있으면 알려주십시오.

답변3

또 다른 변형:

[ -z "$(LC_ALL=C find /var/kafka -mindepth 1 -maxdepth 1 -type d \( -name '*[0-9]' -o -print -quit \))" ]

$?모든 디렉터리 이름이 숫자로 끝나면 true(0)를 반환합니다.

관련 정보