특정 숫자 범위 내의 홀수를 포함하는 모든 파일을 나열하는 방법은 무엇입니까?

특정 숫자 범위 내의 홀수를 포함하는 모든 파일을 나열하는 방법은 무엇입니까?

"file000.txt"부터 "file999.txt"까지의 파일이 포함된 데이터 세트가 있습니다.

와일드카드를 사용하여 0부터 500까지 모든 파일을 나열할 수 있다는 것을 알고 있습니다.

ls file{0..500}

홀수를 포함하는 모든 파일을 찾을 수 있습니다

ls file*[1,3,5,7,9].txt

저는 Unix를 처음 사용하기 때문에 이 두 매개변수를 결합하여 0-500 범위의 홀수를 포함하는 모든 파일을 한 줄에 나열하는 방법을 잘 모르겠습니다. 나는 이것이 빠른 수정임에 틀림없다고 확신하지만 그것을 알아낼 수는 없습니다.

답변1

그리고 zsh:

set -o extendedglob
print -rC1 -- file(<0-500>~^*[13579]).txt

(zsh에서) 는 {0..50}전역 연산자가 아니라 해당 파일이 존재하는지 여부를 확장하는 중괄호 확장입니다.

<0-500>(zsh에 고유하며 아직 다른 쉘에서는 복사되지 않음)은 0에서 500 사이의 숫자를 구성하는 ASCII 십진수 시퀀스와 일치하는 glob 연산자입니다.

~~이다와는 별개로(설마) 연산자 ^이며아니요. A~BA이다설마B A~^B는 A이다아니 아니B, 그러니까 A와 B.

에서는 bash다음과 같은 작업을 수행할 수 있습니다.

shopt -s failglob extglob
printf '%s\n' file*(0)[01234][0123456789][13579].txt

*(0)(ksh의 확장된 glob 연산자)는 임의 개수의 0이면 0에서 4까지의 숫자, 0에서 9까지의 숫자, 집합 13579의 숫자를 예상합니다.

이제 중괄호 확장은 zsh 및 bash(및 ksh931 및 ksh931)에 해당 파일이 있는지에 관계없이 yash -o braceexpand1, 3, ... 499로 확장됩니다 .

printf '%s\n' file{1..499..2}.txt

기타 참고사항:

  • [1,3,5,7,9]와 동일하며 [13579,]세트의 모든 문자와 일치합니다. 당신은 대신 원합니다 [13579].
  • bash(zsh 아님)에서는 [0-9]수백 개의 서로 다른 숫자 유사 문자를 일치시키는 것이 일반적입니다. [0123456789]이러한 10개의 ASCII 10진수 문자만 일치시키려면 이 옵션을 사용하십시오.
  • -d이 옵션을 전달하지 않고 ls이 옵션에 전달된 모든 파일 filexxx.txt(셸의 중괄호 확장 또는 파일 이름 생성(일명 와일드카드)의 결과로)은 유형입니다.목차, ls디렉토리의 내용을 나열합니다. 그러나 여기서는 셸에서 제공한 목록만 정렬되어 인쇄되므로(파일이 존재하는지 확인한 후) 기본적으로 중복 -d됩니다 . 또는 유틸리티를 사용하여 목록을 인쇄 할 수도 있습니다 .lslsprintprintf

1 {a,b}Braces 확장은 70년대 후반 csh에서 이루어졌고, zsh는 90 에{4..10}초반년대 이를 확장했습니다(그리고 ksh93 AFAIK를 사용했지만 zsh는 처음부터 이 작업을 수행했으며 일반적으로 별도의 패딩 연산자가 있습니다.{a-zXYZ}braceccl{1..400..2%04d}{1..400.2}%04d{0001..0400}

답변2

ls file[0-4][0-9][13579].txt홀수로 끝나는 파일을 나열하는 데 사용되며 , ls file[0-4][13579][0-9].txt중간에 홀수로 끝나는 파일을 나열하는 데 사용됩니다.

마지막 ls는

 ls file[0-4][0-9][13579].txt file[0-4][13579][0-9].txt file[13][0-9][0-9].txt

file*[1,3,5,7,9].txt일치한다는 점에 유의하십시오 file100001.txt. 이는 귀하가 원하는 것이 아닙니다. 또한 괄호 안의 구분 기호로 쉼표를 사용하지 않습니다. [1,3,5,7,9]쉼표와 동일하며 [13579,]쉼표와도 일치합니다.

답변3

다른 답변에서 알 수 있듯이 홀수를 찾는 것은 쉽습니다. 주로 마지막 숫자를 보는 것으로 충분하기 때문입니다.

보다 일반적인 경우에는 실제로 숫자를 숫자로 처리해야 합니다. 이 작업을 직접 수행하기는 어렵지만 예를 들어 더 큰 컬렉션을 반복하고 배열에서 일치하는 세트를 선택할 수 있습니다. 셸(특히 Bash)은 이런 종류의 작업을 수행하기에 너무 빠르지는 않지만 수백 또는 수천 개의 파일에 대해서는 그렇게 할 수 있습니다.

다음은 7로 나눌 수 있는 숫자에 대한 파일입니다(Bash에서는 앞에 0이 있는 숫자와 일치합니다).

shopt -s extglob
a=()
for f in file+([0-9]).txt; do 
    n=${f##file*(0)}      # remove leading 'file' and any zeroes
    n=${n%.txt}           # remove tailing '.txt'
    if (( $n % 7 == 0 )); then
        a+=("$f")
    fi
done
printf "%s\n" "${a[@]}"    # or whatever you do with the filenames

또는 먼저 숫자를 반복할 수 있습니다(Bash 및 기타, 앞에 0이 있는 숫자는 표시되지 않음).

a=()
for ((i = 0; i <= 500; i += 7)); do
    f="file${i}.txt"
    if [[ -e "$f" ]]; then
        a+=("$f")
    fi
done
printf "%s\n" "${a[@]}"

또는 인위적으로 구형으로 만들어진 중괄호 확장을 통해 문자열 묶음을 생성하여 일치하지 않는 문자열을 제거하도록 쉘에 지시할 수 있습니다. ( [f]여기에는 문자만 일치해야 하는 패턴이 있습니다. f아마도) 이것은 좀 더 무차별적이고 아마도 효율적이지는 않지만 명시적인 루프를 사용하지 않기 때문에 더 간단합니다. (Bash는 앞에 0이 붙은 숫자도 표시하지 않습니다.)

shopt -s nullglob   # remove non-matching globs
shopt -u failglob
a=([f]ile{0..499..7}.txt)
printf "%s\n" "${a[@]}"

관련 정보