显示具有特定模式的文件列表

显示具有特定模式的文件列表

我有很多名为以下模式之一的文件:

1    Surname, Name - Title. Subtitle.extension

2    Surname, N. Surname, N. - Title. Subtitle.extension

3    VV. AA. - Title. Subtitle.extension

(副标题是可选的)

我只需要分别列出具有模式 1、2 或 3 的文件。这是一个例子:

....... files in ~/books:
Deleuze, G. Guattari, F. - Mil mesetas.pdf
Sloterdijk, Peter - parque humano.pdf
VV. AA. - Fenomenología de la percepción. Ensayos sobre Merleau-Ponty.pdf
Marx, K. Engels, F. - Capital I.epub
Aristóteles - Metafísica.epub
VV. AA. - Lógica Simbólica.pdf
Zizek, Slavoj - Menos que nada. Hegel y la sombra del materialismo histórico.

....... show filenames with one author:
Sloterdijk, Peter - parque humano.pdf
Aristóteles - Metafísica.epub
Zizek, Slavoj - Menos que nada. Hegel y la sombra del materialismo histórico.


....... show filenames with two authors:
Marx, K. Engels, F. - Capital I.epub
Deleuze, G. Guattari, F. - Mil mesetas.pdf

....... show filenames with "VV. AA.":
VV. AA. - Lógica Simbólica.pdf
VV. AA. - Fenomenología de la percepción. Ensayos sobre Merleau-Ponty.pdf

答案1

zsh

set -o extendedglob
one-author()   print -rC1 - ~/books/(([^,-]#,)(#c0,1)[^,-]#~'VV. AA.'*)-*(ND:t)
two-authors()  print -rC1 - ~/books/([^,-]#,)(#c2)[^,-]#-*(ND:t)
vv-aa-author() print -rC1 - ~/books/'VV. AA.'*(ND:t)

然后:

$ one-author
Aristóteles - Metafísica.epub
Sloterdijk, Peter - parque humano.pdf
Zizek, Slavoj - Menos que nada. Hegel y la sombra del materialismo histórico.
$ two-authors
Deleuze, G. Guattari, F. - Mil mesetas.pdf
Marx, K. Engels, F. - Capital I.epub
$ vv-aa-author
VV. AA. - Fenomenología de la percepción. Ensayos sobre Merleau-Ponty.pdf
VV. AA. - Lógica Simbólica.pdf

上面的全局运算符是:

  • #(相当于 regex *)前一个原子出现 0 次或多次
  • (#c<min>,<mac>)(相当于 regex {<min>,<max>})表示前一个原子出现的最小到最大次数(注意,x(#c0,1)我们也可以这样做(x|))。
  • pattern1~pattern2:匹配模式1和不模式2。
  • (...)用于分组。
  • (ND:t)是一个 glob 限定符,Nfor nullglob(如果没有匹配文件则不会失败),Dfor dotglob(包括隐藏文件),:t修饰符仅扩展到尾巴文件的(基本名称)。

这些过滤器文件名基于,第一次出现之前的 s数-(并且VV. AA.专门针对单作者文件进行处理)。

如果"-"(但不是" - ") 可能出现在作者姓名中,并且 两侧始终至少有一个 SPC 将-作者与标题分隔开,您可以将其更改为:

set -o extendedglob
one-author()   print -rC1 - ~/books/(([^,]#,)(#c0,1)[^,]#~'VV. AA.'*~*' - '*)' - '*(ND:t)
two-authors()  print -rC1 - ~/books/(([^,]#,)(#c2)[^,]#~*' - '*)' - '*(ND:t)
vv-aa-author() print -rC1 - ~/books/'VV. AA.'*(ND:t)

使用bashshell,您可以执行以下操作:

shopt -s nullglob dotglob extglob
print-tails() {
  (( $# == 0 )) || printf '%s\n' "${@##*/}"
}
one-author() {
  print-tails ~/books/!(!(?(*([^,]),)*([^,]))|'VV. AA.'*|*' - '*)' - '*
}
two-authors() {
  print-tails ~/books/!(!(*([^,]),*([^,]),*([^,]))|*' - '*)' - '*
}
vv-aa-authors() {
  print-tails ~/books/'VV. AA.'*
}

使用extglob,支持 ksh 扩展 glob 的子集:

  • *(x)(如 zshx#或 regexp x*):0 个或多个xs。
  • ?(x)(如 zsh 的(x|)x(#c0,1)或 ERE x?):0 或 1 x
  • !(x)(如 zsh 的^x):任何不匹配的内容x
  • 在其中任何一个中,|可以用来表示或者

作为 的等价物zshpattern1~pattern2我们这样做!(!(pattern1)|pattern2)

答案2

重击:

declare -a vv one two

for file in *; do 
    authors=${file%% - *}
    case $authors in
        'VV. AA.') vv+=("$file") ;;
        *)  authors=${authors//, /}
            IFS=' ' read -ra names <<<"$authors"
            (( ${#names[@]} == 1 )) && one+=("$file") || two+=("$file")
            ;;
    esac
done

declare -p one two vv

输出

declare -a one=([0]="Aristóteles - Metafísica.epub" [1]="Sloterdijk, Peter - parque humano.pdf" [2]="Zizek, Slavoj - Menos que nada. Hegel y la sombra del materialismo histórico.")
declare -a two=([0]="Deleuze, G. Guattari, F. - Mil mesetas.pdf" [1]="Marx, K. Engels, F. - Capital I.epub")
declare -a vv=([0]="VV. AA. - Fenomenología de la percepción. Ensayos sobre Merleau-Ponty.pdf" [1]="VV. AA. - Lógica Simbólica.pdf")

如果您想要交互式菜单:

PS3="Select authorship: "
select category in One Two VV quit; do
    case $category in
        One) printf "%s\n" "${one[@]}" ;;
        Two) printf "%s\n" "${two[@]}" ;;
        VV)  printf "%s\n" "${vv[@]}"  ;;
        quit) break ;;
    esac
done

相关内容