是否可以将文件全局链接在一起?

是否可以将文件全局链接在一起?

保存 我有一系列名为{1..40}0.txt(所以10.txt400.txt10)的文件:

➜ 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.txt100.txt200.txt3{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 via 之间的文件进行 glob <100-300>.txt,并且可以对那些可被 100 via 整除的文件进行 glob ^(*00).txt(使用extendedglob设置的选项)。

是否可以将文件全局模​​式一个接一个地链接起来?因此,glob 100-300 个文件,然后 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>.txt选择以 100 到 300 之间的数字开头的文件。

glob 限定符 ,(e['(( $REPLY:r % 100 != 0 ))'])选择“根”(不带扩展名的名称,具有 via :r)不能被 100 整除的文件名。


当然,您也可以通过 glob 限定符来完成这一切:

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

答案2

如果通过一个接一个地链接团,您的意思相当于grep pattern | grep another-patternor 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 中一样,但仅在(...)as内部|也是管道运算符):(patternA|patternB)
  • 与非:(~extendedglob):patternA~patternB
  • NOT:(^带有extendedglob) 或!(pattern)(带有kshglob和不带histexpand或带有不同的字符作为 的第一个字符$HISTCHARS
  • AND:(~^即 AND-NOT-NOT,与extendedglob),或!(!(patternA)|!(patternB))kshglob

作为@Kusalananda 已经表明,您还可以使用eglob 限定符根据任意 shell 代码的执行进一步细化 glob 选择。

你甚至可以做这样的事情:

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

相关内容