파일을 전역적으로 함께 링크하는 것이 가능합니까?

파일을 전역적으로 함께 링크하는 것이 가능합니까?

저장 이름 이 10 {1..40}0.txt인 일련의 파일이 있습니다 .10.txt400.txt

➜ ls
10.txt  60.txt   110.txt  160.txt  210.txt  260.txt  310.txt  360.txt
20.txt  70.txt   120.txt  170.txt  220.txt  270.txt  320.txt  370.txt
30.txt  80.txt   130.txt  180.txt  230.txt  280.txt  330.txt  380.txt
40.txt  90.txt   140.txt  190.txt  240.txt  290.txt  340.txt  390.txt
50.txt  100.txt  150.txt  200.txt  250.txt  300.txt  350.txt  400.txt

100에서 300 사이이지만 100으로 나눌 수 없는 모든 파일을 삭제하고 싶습니다. 지금 바로. 떠나다 {1..9}0.txt, 100.txt, 200.txt, 3{1..9}0.txt:

rm 110.txt  130.txt  150.txt  170.txt  190.txt  220.txt  240.txt  260.txt  280.txt
   120.txt  140.txt  160.txt  180.txt  210.txt  230.txt  250.txt  270.txt  290.txt

zsh에서는 를 통해 100에서 300 사이의 파일을 glob할 수 있고 옵션 세트를 사용하여 <100-300>.txt100으로 나눌 수 있는 파일을 glob할 수 있습니다 .^(*00).txtextendedglob

파일 전역 패턴을 차례로 연결할 수 있습니까?따라서 100-300개의 파일을 glob한 다음 나머지 파일을 glob하여 00?

단일 glob 내에서 이를 수행하는 방법은 제외가 제공되는 <100-300>.txt~(*00).txt곳 입니다 ~(참조zsh 문서). 편집: 글로벌 골프를 플레이하면 다음과 같이 단순화할 수 있습니다 <10-30>0*~*00*.

답변1

$ touch {10..400..10}.txt
$ print -rC1 -- <100-300>.txt(e['(( $REPLY:r % 100 != 0 ))'])
110.txt
120.txt
130.txt
140.txt
150.txt
160.txt
170.txt
180.txt
190.txt
210.txt
220.txt
230.txt
240.txt
250.txt
260.txt
270.txt
280.txt
290.txt

위의 내용으로 touch파일이 생성됩니다.

다음 줄의 비트는 <100-300>.txt100에서 300 사이의 숫자로 시작하는 파일을 선택합니다.

glob 한정자는 100으로 나눌 수 없는 (e['(( $REPLY:r % 100 != 0 ))'])"루트"(확장자가 없는 이름, via 를 통한 이름) 파일 이름을 선택합니다 .:r


물론, glob 한정자를 통해서도 이 작업을 수행할 수 있습니다.

*.txt(e['(( r=$REPLY:r, r >= 100 && r <= 300 && r % 100 != 0 ))'])

답변2

통과되면그룹을 차례로 연결grep pattern | grep another-pattern, 즉 or 와 동등한 것을 의미합니다 grep pattern | grep -v excluded-pattern. 즉, 일치하는 파일 목록을 가져온 다음 두 번째 반복에서 목록을 추가로 구체화하는 경우 ${array:#exclude-pattern}and ${(M)array:#only-pattern}연산자를 사용합니다.

list=(*(N))                      # all non-hidden files
list=(${(M)list:#<100-300>.txt}) # only retain the ones matching that pattern
list=(${list:#*00.txt})          # remove the ones matching that other pattern

그렇지 않은 경우 귀하의 경우 가장 확실한 접근 방식은 ~AND-NOT(예외) 연산자(필수 extendedglob)를 사용하는 것입니다. 다음과 같이 할 수도 있습니다.

list=((<100-300>~*00).txt(N))

"체인"글로벌 운영자는 다음과 같습니다.

  • OR: |(ERE와 같지만 (...)내부 에서만 |파이프 연산자도 마찬가지입니다):(patternA|patternB)
  • 그리고 아님: ( ~그리고 extendedglob):patternA~patternB
  • NOT: ( ^포함 extendedglob) 또는 !(pattern)( 첫 번째 문자와 다른 문자 포함 또는 kshglob제외 )histexpand$HISTCHARS
  • AND: ( ~^즉, AND-NOT-NOT, AND extendedglob) 또는 !(!(patternA)|!(patternB))AND kshglob.

~처럼@Kusalananda가 말했습니다.e, glob 한정자를 사용하여 임의의 셸 코드 실행을 기반으로 glob 선택을 더욱 구체화할 수도 있습니다 .

다음과 같이 할 수도 있습니다.

list=(*(Ne['[[ $REPLY = <100-300>.txt ]] && [[ $REPLY != *00.txt ]]']))

관련 정보