.
├── subdirectory-A
│ ├── 1.jpg
│ ├── 1.tif
│ ├── 2.jpg
│ ├── 2.tif
│ ├── JPEG
│ └── TIF
└── subdirectory-B
├── 1.jpg
├── 1.tif
├── 2.jpg
├── 2.tif
├── JPEG
└── TIF
有人能帮忙吗?我正在尝试找到一种方法,通过在本地父目录中运行 shell 脚本中的 ( ) 将所有.tif
文件移动到 TIF 目录,将所有.jpg
文件移动到 JPEG 目录mv
。我一直在使用
mv *.jpg JPEG/
在每个子目录中,但我需要在包含超过 17K 个目录的档案中执行此作业,并且一次一个目录的手动选项不是一个选项。
答案1
您可以rename
使用bash
的globstar
选项来执行此操作:
shopt -s globstar
rename -n 's/.*\//$&JPEG\//' **/*.jpeg
rename -n 's/.*\//$&TIF\//' **/*.tif
该-n
选项让它只输出它将要做什么,删除它以实际执行移动。这里发生的事情是,由于匹配了任意数量的子目录,因此rename
遍历任何子目录中的每个 eg文件。它用自身()后跟 替换其路径(直到最后一个 的所有内容) ,从而有效地将文件移动到此目录。.jpeg
**
/
$&
JPEG/
如果参数列表太长,上述命令将会抛出错误。使用此方法可以解决 shell 的ARG_MAX
限制:
printf '%s\0' **/*.jpeg | xargs -0 rename -n 's/.*\//$&JPEG\//'
printf '%s\0' **/*.tif | xargs -0 rename -n 's/.*\//$&TIF\//'
这使用 shell 内置命令printf
来构建一个零分隔的参数列表,该列表通过管道传输到具有最大参数数量的xargs
调用。rename
示例运行
$ tree
.
├── subdirectory-A
│ ├── 1.jpeg
│ ├── 1.tif
│ ├── 2.jpeg
│ ├── 2.tif
│ ├── JPEG
│ └── TIF
└── subdirectory-B
├── 1.jpeg
├── 1.tif
├── 2.jpeg
├── 2.tif
├── JPEG
└── TIF
$ shopt -s globstar
$ rename -n 's/.*\//$&JPEG\//' **/*.jpeg
rename(subdirectory-A/1.jpeg, subdirectory-A/JPEG/1.jpeg)
rename(subdirectory-A/2.jpeg, subdirectory-A/JPEG/2.jpeg)
rename(subdirectory-B/1.jpeg, subdirectory-B/JPEG/1.jpeg)
rename(subdirectory-B/2.jpeg, subdirectory-B/JPEG/2.jpeg)
$ rename 's/.*\//$&JPEG\//' **/*.jpeg
$ printf '%s\0' **/*.tif | xargs -0 rename 's/.*\//$&TIF\//'
$ tree
.
├── subdirectory-A
│ ├── JPEG
│ │ ├── 1.jpeg
│ │ └── 2.jpeg
│ └── TIF
│ ├── 1.tif
│ └── 2.tif
└── subdirectory-B
├── JPEG
│ ├── 1.jpeg
│ └── 2.jpeg
└── TIF
├── 1.tif
└── 2.tif
答案2
我首先想到的是以下 Bash 循环:
#!/bin/bash
for dir in */ # or use: subdirectory*/
do
cd "$dir"
mv *jpg JPG/
mv *tif TIF/
cd ..
done
作为内联命令使用的示例:
$ mkdir -p subdirectory-{A,B}/{TIF,JPG}; touch subdirectory-{A,B}/{1,2}.{jpg,tif}
$ for dir in */; do cd "$dir"; mv *jpg JPG/; mv *tif TIF/; cd ..; done
$ tree
.
├── subdirectory-A
│ ├── JPG
│ │ ├── 1.jpg
│ │ └── 2.jpg
│ └── TIF
│ ├── 1.tif
│ └── 2.tif
└── subdirectory-B
├── JPG
│ ├── 1.jpg
│ └── 2.jpg
└── TIF
├── 1.tif
└── 2.tif
6 directories, 8 files
相关问题:
答案3
既然您提到了“超过 17K 个目录”,find
我xargs
就想到了。
# do this part Only Once
cat >./TheScript <<"EOF"
#!/bin/bash
while $# -gt 0 ; do
cd "$1"
find . -maxdepth 1 -type f -name '*.jpg' -print | xargs --no-run-if-empty mv --target-directory=JPG
find . -maxdepth 1 -type f -name '*.tif' -print | xargs --no-run-if-empty mv --target-directory=TIF
cd "$OLDPWD"
shift
done
exit 0
EOF
chmod +x ./TheScript
# end of "Only Once"
find . -type d \! -name 'JPG' -a \! -name 'TIF` -print |\
xargs $PWD/.TheScript