Automator/Apple 脚本:将具有相同前缀的文件移动到新文件夹中。文件夹名称必须是文件前缀
Automator/Apple Script: Move files with same prefix on a new folder. The folder name must be the files prefix
我是一名摄影师,我在一个文件夹中有多个 jpg 服装文件。文件名结构为:
TYPE_FABRIC_COLOR(示例:BU23W02CA_CNU_RED、BU23W02CA_CNU_BLUE、BU23W23MG_LINO_WHITE)
我必须将相同类型 (BU23W02CA) 的文件移动到一个名为 TYPE 的文件夹中。
例如:
MAIN FOLDER>
BU23W02CA_CNU_RED.jpg, BU23W02CA_CNU_BLUE.jpg, BU23W23MG_LINO_WHITE.jpg
变成:
MAIN FOLDER>
BU23W02CA_CNU > BU23W02CA_CNU_RED.jpg, BU23W02CA_CNU_BLUE.jpg
BU23W23MG_LINO > BU23W23MG_LINO_WHITE.jpg
这是一些脚本。
V1
#!/bin/bash
find . -maxdepth 1 -type f -name "*.jpg" -print0 | while IFS= read -r -d '' file
do
# Extract the directory name
dirname=$(echo "$file" | cut -d'_' -f1-2 | sed 's#\./\(.*\)##')
#DEBUG echo "$file --> $dirname"
# Create it if not already existing
if [[ ! -d "$dirname" ]]
then
mkdir "$dirname"
fi
# Move the file into it
mv "$file" "$dirname"
done
- 它假定
find
列表中的所有文件都具有您在问题中描述的格式,即 TYPE_FABRIC_COLOR.ext
。
dirname
是提取文件名中_
分隔的前两个单词。
- 由于
find
列出了带有 ./
前缀的文件,它也从 dirname
中删除(这就是 sed
命令的作用)。
-
find
指定要考虑的文件名 *.jpg
。如果您想限制在移动中考虑哪些文件,您可以将其更改为其他内容。
- 此版本遍历每个文件,创建一个包含前两部分的目录(如果它不存在),然后将文件移入其中。
- 如果您想查看脚本对每个文件执行的操作,可以将选项
-v
添加到 mv
命令。我用它来调试。
但是,由于它逐个循环遍历每个文件,因此对于大量文件这可能需要时间,因此是下一个版本。
V2
#!/bin/bash
while IFS= read -r dirname
do
echo ">$dirname"
# Create it if not already existing
if [[ ! -d "$dirname" ]]
then
mkdir "$dirname"
fi
# Move the file into it
find . -maxdepth 1 -type f -name "${dirname}_*" -exec mv {} "$dirname" \;
done < <(find . -maxdepth 1 -type f -name "*.jpg" -print | sed 's#^\./\(.*\)_\(.*\)_.*\..*$#_#' | sort | uniq)
- 此版本在目录名称而不是每个文件上循环。
- 最后一行做了“魔术”。它
find
所有文件,并立即提取前两个单词(sed
)。然后这些词被 sort
ed 和 "uniq
ued".
while
循环然后一个一个地创建每个目录。
-
while
循环中的 find
将所有与正在处理的目录匹配的文件移动到其中。为什么我不简单地做 mv ${dirname}_* ${dirname}
?由于 *
通配符的扩展可能导致 mv
命令的参数列表过长。使用 find
确保它即使在大量文件上也能工作。
建议单行awk
脚本:
echo "$(ls -1 *.jpg)"| awk '{system("mkdir -p " OFS );system("mv "[=10=]" " OFS )}' FS=_ OFS=_
解释:
echo "$(ls -1 *.jpg)"
: 列出当前目录下的所有jpg文件,每行一个文件
FS=_
:将awk
字段分隔符设置为_
$1=type $2=fabric $3=color.jpg
OFS=_
:设置awk
输出字段分隔符为_
awk脚本解释
{ # for each file name from list
system ("mkdir -p " OFS ); # execute "mkdir -p type_fabric"
system ("mv " [=11=] " " OFS ); # execute "mv current-file to type_fabric"
}
我是一名摄影师,我在一个文件夹中有多个 jpg 服装文件。文件名结构为:
TYPE_FABRIC_COLOR(示例:BU23W02CA_CNU_RED、BU23W02CA_CNU_BLUE、BU23W23MG_LINO_WHITE)
我必须将相同类型 (BU23W02CA) 的文件移动到一个名为 TYPE 的文件夹中。
例如:
MAIN FOLDER>
BU23W02CA_CNU_RED.jpg, BU23W02CA_CNU_BLUE.jpg, BU23W23MG_LINO_WHITE.jpg
变成:
MAIN FOLDER>
BU23W02CA_CNU > BU23W02CA_CNU_RED.jpg, BU23W02CA_CNU_BLUE.jpg
BU23W23MG_LINO > BU23W23MG_LINO_WHITE.jpg
这是一些脚本。
V1
#!/bin/bash
find . -maxdepth 1 -type f -name "*.jpg" -print0 | while IFS= read -r -d '' file
do
# Extract the directory name
dirname=$(echo "$file" | cut -d'_' -f1-2 | sed 's#\./\(.*\)##')
#DEBUG echo "$file --> $dirname"
# Create it if not already existing
if [[ ! -d "$dirname" ]]
then
mkdir "$dirname"
fi
# Move the file into it
mv "$file" "$dirname"
done
- 它假定
find
列表中的所有文件都具有您在问题中描述的格式,即TYPE_FABRIC_COLOR.ext
。 dirname
是提取文件名中_
分隔的前两个单词。- 由于
find
列出了带有./
前缀的文件,它也从dirname
中删除(这就是sed
命令的作用)。 -
find
指定要考虑的文件名*.jpg
。如果您想限制在移动中考虑哪些文件,您可以将其更改为其他内容。 - 此版本遍历每个文件,创建一个包含前两部分的目录(如果它不存在),然后将文件移入其中。
- 如果您想查看脚本对每个文件执行的操作,可以将选项
-v
添加到mv
命令。我用它来调试。
但是,由于它逐个循环遍历每个文件,因此对于大量文件这可能需要时间,因此是下一个版本。
V2
#!/bin/bash
while IFS= read -r dirname
do
echo ">$dirname"
# Create it if not already existing
if [[ ! -d "$dirname" ]]
then
mkdir "$dirname"
fi
# Move the file into it
find . -maxdepth 1 -type f -name "${dirname}_*" -exec mv {} "$dirname" \;
done < <(find . -maxdepth 1 -type f -name "*.jpg" -print | sed 's#^\./\(.*\)_\(.*\)_.*\..*$#_#' | sort | uniq)
- 此版本在目录名称而不是每个文件上循环。
- 最后一行做了“魔术”。它
find
所有文件,并立即提取前两个单词(sed
)。然后这些词被sort
ed 和 "uniq
ued". while
循环然后一个一个地创建每个目录。-
while
循环中的find
将所有与正在处理的目录匹配的文件移动到其中。为什么我不简单地做mv ${dirname}_* ${dirname}
?由于*
通配符的扩展可能导致mv
命令的参数列表过长。使用find
确保它即使在大量文件上也能工作。
建议单行awk
脚本:
echo "$(ls -1 *.jpg)"| awk '{system("mkdir -p " OFS );system("mv "[=10=]" " OFS )}' FS=_ OFS=_
解释:
echo "$(ls -1 *.jpg)"
: 列出当前目录下的所有jpg文件,每行一个文件
FS=_
:将awk
字段分隔符设置为_
$1=type $2=fabric $3=color.jpg
OFS=_
:设置awk
输出字段分隔符为_
awk脚本解释
{ # for each file name from list
system ("mkdir -p " OFS ); # execute "mkdir -p type_fabric"
system ("mv " [=11=] " " OFS ); # execute "mv current-file to type_fabric"
}