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

Bash 将文件从一个目录复制到多个目录,bash,cp,Bash,Cp,目录(mydir)有1000个文件(ls | wc-l),但我只想将那些带有file.num.txt的文件复制到目录num。以下是一个例子: mydir 文件1 file.1.txt 档案2 file.2.txt … /home/user1/store dir有如下目录 dir1 dir2 … 所以我想把file.1.txt复制到dir1,dir2中的file.2.txt等等 这应该有效: #!/bin/bash src="mydir" dest="/home/user1/store"

目录(mydir)有1000个文件(ls | wc-l),但我只想将那些带有file.num.txt的文件复制到目录num。以下是一个例子:

  • mydir
    • 文件1
    • file.1.txt
    • 档案2
    • file.2.txt
  • /home/user1/store dir有如下目录
    • dir1
    • dir2
  • 所以我想把file.1.txt复制到dir1dir2中的file.2.txt等等

    这应该有效:

    #!/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]}
    包含根据模式
    $regex
    匹配的
    $file
    中捕获的组#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
    
    第一部分评估为“真”或“假”,是执行“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
    
    有关其他安装选项,请参阅

    了解更多信息

    请参阅更多示例:

    观看介绍视频:

    浏览本教程:


    注册电子邮件列表以获得支持:

    我想知道是否可以通过
    find
    的-exec参数或
    xargs
    来实现这一点,但我一直坚持使用变量替换文件名

    所以我就在巴什的电话里结束了

    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
    

    你试过了吗?你需要一个glob上的循环和一些基本的shell变量扩展(或者使用
    cut
    /
    awk
    /等等)来实现这一点。是的,我想知道mkdir-p,但是你已经解释过了,在我的情况下,这是不必要的,非常感谢你。现在它就像一个符咒。谢谢。平行似乎是对未来的承诺;我目前无法在我的系统上访问它。我应该看看链接,以获得一个头部。谢谢。
    并行
    很好,但是复制文件纯粹是I/O绑定的。在这种特殊情况下,增加并行性只会降低速度。@lcd047过去是这样,但现在已经不是这样了:我使用的RAID如果并行运行10个作业,速度将提高6倍。如果我并行运行更少或更多的作业,RAID会更慢。对于SSD磁盘,情况就更糟了。因此,唯一仍然有效的建议是:测量哪个更适合您,并相应地调整--jobs。即使使用RAID,
    parallel
    所做的事情也不合适,因为它使用CPU内核数来设置并行运行的作业数。CPU内核的数量与I/O完全无关。而且,我怀疑读这篇文章的绝大多数人都不会有RAID 10或通过光纤通道连接的SAN。@lcd047。。。这就是为什么你要调整工作的原因。我不知道你为什么要启动RAID 10和SAN。我对速度的观察适用于很多场景:SSD、任何RAID和网络文件系统,仅举三种。唯一仍然有效的建议是:衡量哪种方法更适合你。