将文件从一个目录复制到多个目录

copy files from a directory to multiple directories

目录 (mydir) 有 1000 个文件 (ls | wc -l) 但我只想复制 file.num.txt 到目录 num。这是一个例子:

  1. 我的目录
    • 文件.1
    • 文件.1.txt
    • 文件.2
    • 文件.2.txt
    • ...
  2. /home/user1/store 目录有类似的目录
    • 目录 1
    • 目录 2
    • ...

所以我想复制file.1.txtdir1,file.2.txtdir2 等等。

这应该有效:

#!/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