将目录中带有赞助人的文件移动到特定目录
moving files with patron in directories to specific directory
我得到了一堆名称如下的目录(我无法更改生成的任何内容):
yyyy-MM-dd hh.mm.ss DIR1 File 01 random_number/
yyyy-MM-dd hh.mm.ss DIR2 File 06 random_number/
yyyy-MM-dd hh.mm.ss DIR3 File 11 random_number/
etc
其中 random_number
是一个 11 位随机整数。每个目录都有一个名为 something.ext
的文件(每个目录的名称相同)。还有一个名为 done
的目录,我将已经处理过的目录移动到其中。
我重命名 something.ext
文件并将它们复制到另一个目录,手动像这样:
cd yyyy-MM-dd\ hh.mm.ss\ DIR1\ File\ 01\ random_number/
mv something.ext File\ 01.ext
cp File\ 01.ext /path/to/DIR1/
cd ..
mv yyyy-MM-dd\ hh.mm.ss\ DIR1\ File\ 01\ random_number/ done/
cd yyyy-MM-dd\ hh.mm.ss\ DIR2\ File\ 06\ random_number/
mv something.ext File\ 06.ext
cp File\ 06.ext /path/to/DIR2/
cd ..
mv yyyy-MM-dd\ hh.mm.ss\ DIR2\ File\ 06\ random_number/ done/
etc
有什么方法可以通过脚本自动执行此操作吗?我不太擅长过滤名称和东西...我熟悉 bash 和 python 脚本...
您可以在 for 循环内使用 =~
运算符进行正则表达式模式匹配,这是从 bashv3+
开始的 bash 的一个特性。 subshell 在使用 cd
时很有用,不用担心是否以及何时需要退出当前目录。
#!/usr/bin/env bash
regex='^(.+) (.+) (.+) (.+) (.+) (.+)$'
for directory in */; do
if [[ $directory =~ $regex ]]; then
dir_num0="${BASH_REMATCH[3]}"
dir_num1="${BASH_REMATCH[4]} ${BASH_REMATCH[5]}"
(
printf 'Going inside directory [%s]\n' "$directory"
cd "$directory" || exit
echo mv -v -- something.txt "$dir_num1.ext" || exit
echo cp -v -- "$dir_num1.ext" "/path/to/$dir_num0" || exit
)
echo mv -v -- "$directory" done/ || exit
fi
done
对于你给定的样本 input/data 输出是:
Going inside directory [xxx-xx-xx xx.xx.xx DIR3 File 11 x/]
mv -v -- something.txt File 11.ext
cp -v -- File 11.ext /path/to/DIR3
mv -v -- xxx-xx-xx xx.xx.xx DIR3 File 11 x/ done/
Going inside directory [xxx-xx-xx xx.xx.xx DIR1 File 01 xx/]
mv -v -- something.txt File 01.ext
cp -v -- File 01.ext /path/to/DIR1
mv -v -- xxxx-xx-xx xx.xx.xx DIR1 File 01 x/ done/
Going inside directory [xxxx-xx-xx xx.xx.xx DIR2 File 06 x/]
mv -v -- something.txt File 06.ext
cp -v -- File 06.ext /path/to/DIR2
mv -v -- xxxx-xx-xx xx.xx.xx DIR2 File 06 x/ done/
=~
test/regex运算符支持E.R.E
将脚本放入相关目录并执行。或者将脚本放在 PATH
中,然后进入相关 files/directories 的顶级目录。
如果您对输出满意,请删除 echo
。
regex/patternregex='^(.+) (.+) (.+) (.+) (.+) (.+)$'
匹配6个字段space为delimiter/separator。它可以更具体地针对您的目录名称。
类似
regex='^([[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}) ([[:digit:]]{2}\.[[:digit:]]{2}\.[[:digit:]]{2}) (.+) (.+) ([[:digit:]]+) ([[:digit:]]+)/$'
我假设您在初始目录中拥有的只是您的“目录束”加上完成的目录。此外,出于测试目的,我使 /path/to/
等于 ./done/
,以便 /path/to/DIR1/
等于 ./done/DIR1/
,/path/to/DIR2/
等于 ./done/DIR2/
, 等等。我的测试目录树如下所示:
$ find .
.
./done
./done/DIR1
./done/DIR2
./done/DIR3
./yyyy-MM-dd hh.mm.ss DIR3 File 11 random_number
./yyyy-MM-dd hh.mm.ss DIR3 File 11 random_number/something.ext
./yyyy-MM-dd hh.mm.ss DIR2 File 06 random_number
./yyyy-MM-dd hh.mm.ss DIR2 File 06 random_number/something.ext
./yyyy-MM-dd hh.mm.ss DIR1 File 01 random_number
./yyyy-MM-dd hh.mm.ss DIR1 File 01 random_number/something.ext
$
您可以通过一个简单的 bash 循环实现您的 mv
和 cp
:
for i in *; do
if [ "$i" == "done" ]; then
continue;
fi;
file=$(echo $i | awk '{print " " }').ext;
todir=./done/$(echo $i | awk '{print }');
mv "$i/something.ext" "$i/$file";
cp "$i/$file" "$todir";
mv "$i" done;
done
这是运行脚本后的目录树和文件:
$ find .
.
./done
./done/DIR1
./done/DIR1/File 01.ext
./done/DIR2
./done/DIR2/File 06.ext
./done/DIR3
./done/DIR3/File 11.ext
./done/yyyy-MM-dd hh.mm.ss DIR1 File 01 random_number
./done/yyyy-MM-dd hh.mm.ss DIR1 File 01 random_number/File 01.ext
./done/yyyy-MM-dd hh.mm.ss DIR2 File 06 random_number
./done/yyyy-MM-dd hh.mm.ss DIR2 File 06 random_number/File 06.ext
./done/yyyy-MM-dd hh.mm.ss DIR3 File 11 random_number
./done/yyyy-MM-dd hh.mm.ss DIR3 File 11 random_number/File 11.ext
$
我得到了一堆名称如下的目录(我无法更改生成的任何内容):
yyyy-MM-dd hh.mm.ss DIR1 File 01 random_number/
yyyy-MM-dd hh.mm.ss DIR2 File 06 random_number/
yyyy-MM-dd hh.mm.ss DIR3 File 11 random_number/
etc
其中 random_number
是一个 11 位随机整数。每个目录都有一个名为 something.ext
的文件(每个目录的名称相同)。还有一个名为 done
的目录,我将已经处理过的目录移动到其中。
我重命名 something.ext
文件并将它们复制到另一个目录,手动像这样:
cd yyyy-MM-dd\ hh.mm.ss\ DIR1\ File\ 01\ random_number/
mv something.ext File\ 01.ext
cp File\ 01.ext /path/to/DIR1/
cd ..
mv yyyy-MM-dd\ hh.mm.ss\ DIR1\ File\ 01\ random_number/ done/
cd yyyy-MM-dd\ hh.mm.ss\ DIR2\ File\ 06\ random_number/
mv something.ext File\ 06.ext
cp File\ 06.ext /path/to/DIR2/
cd ..
mv yyyy-MM-dd\ hh.mm.ss\ DIR2\ File\ 06\ random_number/ done/
etc
有什么方法可以通过脚本自动执行此操作吗?我不太擅长过滤名称和东西...我熟悉 bash 和 python 脚本...
您可以在 for 循环内使用 =~
运算符进行正则表达式模式匹配,这是从 bashv3+
开始的 bash 的一个特性。 subshell 在使用 cd
时很有用,不用担心是否以及何时需要退出当前目录。
#!/usr/bin/env bash
regex='^(.+) (.+) (.+) (.+) (.+) (.+)$'
for directory in */; do
if [[ $directory =~ $regex ]]; then
dir_num0="${BASH_REMATCH[3]}"
dir_num1="${BASH_REMATCH[4]} ${BASH_REMATCH[5]}"
(
printf 'Going inside directory [%s]\n' "$directory"
cd "$directory" || exit
echo mv -v -- something.txt "$dir_num1.ext" || exit
echo cp -v -- "$dir_num1.ext" "/path/to/$dir_num0" || exit
)
echo mv -v -- "$directory" done/ || exit
fi
done
对于你给定的样本 input/data 输出是:
Going inside directory [xxx-xx-xx xx.xx.xx DIR3 File 11 x/]
mv -v -- something.txt File 11.ext
cp -v -- File 11.ext /path/to/DIR3
mv -v -- xxx-xx-xx xx.xx.xx DIR3 File 11 x/ done/
Going inside directory [xxx-xx-xx xx.xx.xx DIR1 File 01 xx/]
mv -v -- something.txt File 01.ext
cp -v -- File 01.ext /path/to/DIR1
mv -v -- xxxx-xx-xx xx.xx.xx DIR1 File 01 x/ done/
Going inside directory [xxxx-xx-xx xx.xx.xx DIR2 File 06 x/]
mv -v -- something.txt File 06.ext
cp -v -- File 06.ext /path/to/DIR2
mv -v -- xxxx-xx-xx xx.xx.xx DIR2 File 06 x/ done/
=~
test/regex运算符支持E.R.E将脚本放入相关目录并执行。或者将脚本放在
PATH
中,然后进入相关 files/directories 的顶级目录。如果您对输出满意,请删除
echo
。regex/pattern
regex='^(.+) (.+) (.+) (.+) (.+) (.+)$'
匹配6个字段space为delimiter/separator。它可以更具体地针对您的目录名称。
类似
regex='^([[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}) ([[:digit:]]{2}\.[[:digit:]]{2}\.[[:digit:]]{2}) (.+) (.+) ([[:digit:]]+) ([[:digit:]]+)/$'
我假设您在初始目录中拥有的只是您的“目录束”加上完成的目录。此外,出于测试目的,我使 /path/to/
等于 ./done/
,以便 /path/to/DIR1/
等于 ./done/DIR1/
,/path/to/DIR2/
等于 ./done/DIR2/
, 等等。我的测试目录树如下所示:
$ find .
.
./done
./done/DIR1
./done/DIR2
./done/DIR3
./yyyy-MM-dd hh.mm.ss DIR3 File 11 random_number
./yyyy-MM-dd hh.mm.ss DIR3 File 11 random_number/something.ext
./yyyy-MM-dd hh.mm.ss DIR2 File 06 random_number
./yyyy-MM-dd hh.mm.ss DIR2 File 06 random_number/something.ext
./yyyy-MM-dd hh.mm.ss DIR1 File 01 random_number
./yyyy-MM-dd hh.mm.ss DIR1 File 01 random_number/something.ext
$
您可以通过一个简单的 bash 循环实现您的 mv
和 cp
:
for i in *; do
if [ "$i" == "done" ]; then
continue;
fi;
file=$(echo $i | awk '{print " " }').ext;
todir=./done/$(echo $i | awk '{print }');
mv "$i/something.ext" "$i/$file";
cp "$i/$file" "$todir";
mv "$i" done;
done
这是运行脚本后的目录树和文件:
$ find .
.
./done
./done/DIR1
./done/DIR1/File 01.ext
./done/DIR2
./done/DIR2/File 06.ext
./done/DIR3
./done/DIR3/File 11.ext
./done/yyyy-MM-dd hh.mm.ss DIR1 File 01 random_number
./done/yyyy-MM-dd hh.mm.ss DIR1 File 01 random_number/File 01.ext
./done/yyyy-MM-dd hh.mm.ss DIR2 File 06 random_number
./done/yyyy-MM-dd hh.mm.ss DIR2 File 06 random_number/File 06.ext
./done/yyyy-MM-dd hh.mm.ss DIR3 File 11 random_number
./done/yyyy-MM-dd hh.mm.ss DIR3 File 11 random_number/File 11.ext
$