我有很多名为以下模式之一的文件:
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 限定符,N
fornullglob
(如果没有匹配文件则不会失败),D
fordotglob
(包括隐藏文件),: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)
使用bash
shell,您可以执行以下操作:
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#
或 regexpx*
):0 个或多个x
s。?(x)
(如 zsh 的(x|)
或x(#c0,1)
或 EREx?
):0 或 1x
。!(x)
(如 zsh 的^x
):任何不匹配的内容x
。- 在其中任何一个中,
|
可以用来表示或者。
作为 的等价物zsh
,pattern1~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