将文件从一个目录复制到多个目录
copy files from a directory to multiple directories
目录 (mydir) 有 1000 个文件 (ls | wc -l) 但我只想复制 file.num.txt 到目录 num。这是一个例子:
- 我的目录
- 文件.1
- 文件.1.txt
- 文件.2
- 文件.2.txt
- ...
- /home/user1/store 目录有类似的目录
- 目录 1
- 目录 2
- ...
所以我想复制file.1.txt到dir1,file.2.txt 在 dir2 等等。
这应该有效:
#!/bin/bash
src="mydir"
dest="/home/user1/store"
dir="dir" #name of the dir without number, i.e dir from dir1, dir2
regex='(.*\.)([0-9]+)(\.txt$)'
for file in "$src"/*;do
if [[ -f $file ]];then
if [[ $file =~ $regex ]];then
mkdir -p "$dest"/"$dir${BASH_REMATCH[2]}"
cp "$file" "$dest"/"$dir${BASH_REMATCH[2]}"
fi
fi
done
解释:
${BASH_REMATCH[2]}
包含来自 $file
与模式 $regex
匹配的捕获组 #2(这是文件名的数字部分)。模式匹配在if语句中完成:
if [[ $file =~ $regex ]];then
mkdir -p
用于目录结构不存在的情况下,它将创建它。
使用 GNU Parallel 你可以 运行:
parallel '{= $_ = /\.\d+\.txt$/ ? "true" : "false" =} && mkdir -p dir{= s/\D//g =} && cp {} dir{= s/\D//g =}' ::: file.*.txt
第一部分的计算结果为 'true' 或 'false',并且是 'grep' 的一种方式。如果您知道 'file.*.txt' 都是 'file.num.txt' 的形式,那么就不需要了。
如果目录不存在,'mkdir -p' 将创建该目录。
如果第一部分的计算结果为 'true',则需要使用 && 来确保命令仅为 运行。
GNU Parallel 是一个通用的并行器,可以很容易地在同一台机器上或在您可以通过 ssh 访问的多台机器上并行 运行 作业。
如果您有 32 个不同的作业要 运行 在 4 CPU 秒内执行,一个直接的并行化方法是 运行 每个 CPU 8 个作业:
GNU Parallel 在一个进程完成时生成一个新进程 - 保持 CPU 处于活动状态,从而节省时间:
安装
如果 GNU Parallel 未打包用于您的发行版,您可以进行个人安装,这不需要 root 访问权限。这样做可以在 10 秒内完成:
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
有关其他安装选项,请参阅 http://git.savannah.gnu.org/cgit/parallel.git/tree/README
了解更多
查看更多示例:http://www.gnu.org/software/parallel/man.html
观看介绍视频:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
完成教程:http://www.gnu.org/software/parallel/parallel_tutorial.html
注册电子邮件列表以获得支持:https://lists.gnu.org/mailman/listinfo/parallel
我想知道这是否可以通过 find
的 -exec 参数或 xargs
来实现,但我被文件名的变量替换卡住了。
所以我最终选择了 bash 的管道,而
find mydir/ -maxdepth 1 -type f -regex ".*\.[0-9]+\(\|\.txt\)" | \
while read line; do num=${line%\.txt}; \
cp ${line} /home/user1/store/dir${num##*\.}; \
done
目录 (mydir) 有 1000 个文件 (ls | wc -l) 但我只想复制 file.num.txt 到目录 num。这是一个例子:
- 我的目录
- 文件.1
- 文件.1.txt
- 文件.2
- 文件.2.txt
- ...
- /home/user1/store 目录有类似的目录
- 目录 1
- 目录 2
- ...
所以我想复制file.1.txt到dir1,file.2.txt 在 dir2 等等。
这应该有效:
#!/bin/bash
src="mydir"
dest="/home/user1/store"
dir="dir" #name of the dir without number, i.e dir from dir1, dir2
regex='(.*\.)([0-9]+)(\.txt$)'
for file in "$src"/*;do
if [[ -f $file ]];then
if [[ $file =~ $regex ]];then
mkdir -p "$dest"/"$dir${BASH_REMATCH[2]}"
cp "$file" "$dest"/"$dir${BASH_REMATCH[2]}"
fi
fi
done
解释:
${BASH_REMATCH[2]}
包含来自 $file
与模式 $regex
匹配的捕获组 #2(这是文件名的数字部分)。模式匹配在if语句中完成:
if [[ $file =~ $regex ]];then
mkdir -p
用于目录结构不存在的情况下,它将创建它。
使用 GNU Parallel 你可以 运行:
parallel '{= $_ = /\.\d+\.txt$/ ? "true" : "false" =} && mkdir -p dir{= s/\D//g =} && cp {} dir{= s/\D//g =}' ::: file.*.txt
第一部分的计算结果为 'true' 或 'false',并且是 'grep' 的一种方式。如果您知道 'file.*.txt' 都是 'file.num.txt' 的形式,那么就不需要了。
如果目录不存在,'mkdir -p' 将创建该目录。
如果第一部分的计算结果为 'true',则需要使用 && 来确保命令仅为 运行。
GNU Parallel 是一个通用的并行器,可以很容易地在同一台机器上或在您可以通过 ssh 访问的多台机器上并行 运行 作业。
如果您有 32 个不同的作业要 运行 在 4 CPU 秒内执行,一个直接的并行化方法是 运行 每个 CPU 8 个作业:
GNU Parallel 在一个进程完成时生成一个新进程 - 保持 CPU 处于活动状态,从而节省时间:
安装
如果 GNU Parallel 未打包用于您的发行版,您可以进行个人安装,这不需要 root 访问权限。这样做可以在 10 秒内完成:
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
有关其他安装选项,请参阅 http://git.savannah.gnu.org/cgit/parallel.git/tree/README
了解更多
查看更多示例:http://www.gnu.org/software/parallel/man.html
观看介绍视频:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
完成教程:http://www.gnu.org/software/parallel/parallel_tutorial.html
注册电子邮件列表以获得支持:https://lists.gnu.org/mailman/listinfo/parallel
我想知道这是否可以通过 find
的 -exec 参数或 xargs
来实现,但我被文件名的变量替换卡住了。
所以我最终选择了 bash 的管道,而
find mydir/ -maxdepth 1 -type f -regex ".*\.[0-9]+\(\|\.txt\)" | \
while read line; do num=${line%\.txt}; \
cp ${line} /home/user1/store/dir${num##*\.}; \
done