bash根据文件名将文件移动到子目录

bash根据文件名将文件移动到子目录,bash,Bash,我有这样命名的文件: 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 A-2450.pdf A-6780.pdf B-1230.pdf B-2450.pdf B-6780.pdf A - 000 - 001 -... - 999 B - 000 - 001

我有这样命名的文件:

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
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中正确使用反向引用和捕获组


谢谢你的帮助

bash中的正则表达式支持与
[[$string=~$Regex]]
一起使用,并将捕获组放置在数组
bash\u 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

bash中的正则表达式支持与
[[$string=~$Regex]]
一起使用,并将捕获组放置在数组
bash\u 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

您试图实现的是所谓的反向引用。不幸的是,球状表达式没有这样的概念。例如:

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
或者更聪明一点,就像

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
形成对比。

您试图实现的是所谓的反向引用。不幸的是,球状表达式没有这样的概念。例如:

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
或者更聪明一点,就像

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
形成对比。

您想要一个问题告诉您如何使用正则表达式,还是一个答案告诉您如何使用正则表达式?请注意,
+([A-Z]-[0-9][0-9][0-9]*.pdf)
是一个extglob,而不是regex,extglob没有捕获组。这更像是一个ZSH(请参见
zmv
$1
是指调用脚本/函数/etc时使用的参数;它与任何类型的shell内置正则表达式功能都没有关系。您想要一个问题来告诉您如何使用正则表达式,还是一个答案来告诉您如何使用正则表达式?请注意,
+([A-Z]-[0-9][0-9][0-9]*.pdf)
是一个extglob,而不是regex,extglob没有捕获组。这更像是一个ZSH(请参见
zmv
$1
是指调用脚本/函数/etc时使用的参数;它与任何类型的shell内置正则表达式功能无关。