"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~B
A이다설마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 braceexpand
1, 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
됩니다 . 또는 유틸리티를 사용하여 목록을 인쇄 할 수도 있습니다 .ls
ls
print
printf
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[@]}"