代码之家  ›  专栏  ›  技术社区  ›  mahemoff

Bash:递归复制命名文件,保留文件夹结构

  •  86
  • mahemoff  · 技术社区  · 15 年前

    我希望:

    cp -R src/prog.js images/icon.jpg /tmp/package
    

    将在目标目录中产生对称结构:

    /tmp
    |
    +-- package
        |
        +-- src
        |   |
        |   +-- prog.js
        |
        +-- images
            |
            +-- icon.jpg
    

    是否有一个简单的bash函数可用于将所有文件(包括通配符指定的文件(例如src/*.js))复制到目标目录中的正确位置。有点像“对于每个文件,运行 mkdir -p $(dirname "$file"); cp "$file" $(dirname "$file") “,但也许只有一个命令。

    This is a relevant thread, which suggests it's not possible. 不过,作者的解决方案对我来说没什么用处,因为我只想提供一个文件列表,不管是否通配符,并将所有文件复制到目标目录。IIRC MS-DOS xcopy可以做到这一点,但似乎没有与cp等效的功能。

    6 回复  |  直到 9 年前
        1
  •  156
  •   ustun    15 年前

    您是否尝试过使用--parents选项?我不知道OSX是否支持这一点,但这在Linux上是可行的。

    cp --parents src/prog.js images/icon.jpg /tmp/package
    

    rsync -R src/prog.js images/icon.jpg /tmp/package
    

        2
  •  23
  •   Randy Proctor    15 年前

    单向:

    tar cf - <files> | (cd /dest; tar xf -)
    
        3
  •  19
  •   Jonathan Leffler    15 年前

    或者,如果您是老派,请使用cpio:

    cd /source;
    find . -print | cpio -pvdmB /target
    

    显然,您可以根据自己的心意筛选文件列表。

    '-p'选项用于“直通”模式(与输入的'-i'或输出的'-o'相反)。“-v”是详细的(列出正在处理的文件)。“-m”保留修改时间。“-B”表示使用“大块”(其中大块是5120字节,而不是512字节);这几天可能没有效果。

        4
  •  18
  •   Ryan Bright    15 年前

    rsync's -R option

    $ rsync -Rv src/prog.js images/icon.jpg /tmp/package/
    images/
    images/icon.jpg
    src/
    src/prog.js
    
    sent 197 bytes  received 76 bytes  546.00 bytes/sec
    total size is 0  speedup is 0.00
    

    样本结果:

    $ find /tmp/package
    /tmp/package
    /tmp/package/images
    /tmp/package/images/icon.jpg
    /tmp/package/src
    /tmp/package/src/prog.js
    
        5
  •  2
  •   Aif    15 年前
        6
  •  1
  •   Jonathan Leffler    9 年前

    尝试

    for f in src/*.js; do cp $f /tmp/package/$f; done
    

    所以对于你最初所做的。。。

    for f in `echo "src/prog.js images/icon.jpg"`; do cp $f /tmp/package/$f; done
    

    v="src/prog.js images/icon.jpg"; for f in $v; do cp $f /tmp/package/$f; done