我有这样命名的文件:
A-1230.pdf
A-2450.pdf
A-6780.pdf
B-1230.pdf
B-2450.pdf
B-6780.pdf
...和这样的目录结构:
A
- 000
- 001
-...
- 999
B
- 000
- 001
-...
- 999
否,我想将文件移动到其相应的子目录。意思
A-1230.pdf goes into A -> 123
B-2450.pdf goes into B -> 245
以此类推。
我用bash尝试了以下方法:
mv +([A-Z]-[0-9][0-9][0-9]*.pdf) $1/$2$3$4
但这不起作用。如何在bash中正确使用反向引用并捕获组?
感谢您的帮助!
答案 0 :(得分:3)
bash对正则表达式的支持与[[ $string =~ $regex ]]
一起使用,并将捕获组放置在数组BASH_REMATCH
中。
for file in ?-*.pdf; do
[[ $file =~ ([[:alpha:]])-([[:digit:]]{3}).* ]] || continue
mkdir -p -- "${BASH_REMATCH[1]}/${BASH_REMATCH[2]}" || continue
mv -- "$file" "${BASH_REMATCH[1]}/${BASH_REMATCH[2]}/"
done
答案 1 :(得分:0)
您试图实现的是所谓的反向引用。不幸的是,球状表达式没有这样的概念。表达式,例如:
mv (*).pdf $1/
cp ([0-9])-(*).txt $2-$1.text
在任何shell(bash,zsh,ksh,csh)中根本不可能。
存在解决方法,方法是遍历每个文件并对其进行后期处理:
for file in [A-Z]-[0-9][0-9][0-9]*.pdf; do
dir="${file:0:5}"; dir="${dir/-/\/}"
mkdir -p "$dir"
mv "$file" "$dir"
done
或更聪明,如Charles Duffy
ZSH为此任务开发了一套单独的工具(zcp
,zmv
和zln
),这些工具可以进行反向引用。因此,您的任务可以按以下方式执行:
zmv -n '([A-Z])-([0-9][0-9][0-9])[0-9].pdf' '$1/$2/'
-n
标志显示了将要执行的操作,但实际上并未执行该操作,因为它作为试运行。删除该标志以执行实际移动。
注意:ZSH没有针对球形表达式的反向引用。注意上面的zmv
示例中使用的单引号。他们禁止滚球。 FROM和DEST部分是这些工具的自变量。该工具也未在任何$PATH
中找到,因为它们是zsh系统的一部分。这与实际的二进制文件cp
,mv
和ln
不同。