复制文件及其(最后)文件夹

时间:2012-03-31 18:11:13

标签: linux bash shell find

我可以使用find -exec命令查找并将所有文件复制到给定文件夹。 但我需要做的是找到并复制给定路径中的所有文件及其保存文件夹。所以......

/path/to/file/is/abc.txt
/another/file/is/here/xyz.txt

我需要将这两个文件及其路径复制到以下文件夹:

/ MySQL的/数据/

新文件结构将如下所示......

/mysql/data/is/abc.txt
/mysql/data/here/xyz.txt

这样做是为了避免可能覆盖重复的文件名。最后的文件夹名称将是唯一的,但文件名可能相同。

这样做的最佳方式是什么?

4 个答案:

答案 0 :(得分:3)

这是一个简洁的脚本,附带相当长的解释 *

for oldpath in $your_file_list; do
    mv ${oldpath} /mysql/data${oldpath##$(dirname $(dirname $oldpath))}
done

工作原理

  • dirname实用程序会删除路径中包含最后一个正斜杠(/)的所有内容。调用它两次将删除所有内容,包括倒数第二个斜杠。

  • 习语$(command with params)使用参数command执行with params并返回输出。

  • 成语${var##prefix}会删除已移除var的变量prefix的内容。

分步分析

如果oldpath/path/to/file/is/abc.txt,则为:

  • dirname $oldpath/path/to/file/is
  • dirname $(dirname $oldpath)/path/to/file
  • ${oldpath##$(dirname $(dirname $oldpath))}/is/abc.txt

是原始路径中将附加到新路径的部分。


* 优雅 adj。软件:任何实现算法的软件,其解释更长而不是实施本身。

答案 1 :(得分:1)

您将不得不编写此程序的脚本/编程。

快速python示例如下:

import os
import shutils
src_root = '/path/to/walk/'
dst_root = '/mysql/data/'
for root,dirs,files in os.walk(src_root):
    for file in files:
        dst_path = os.path.split(root)[1]
        dst_path = os.path.join(dst_root, dst_path)
        os.makedirs(dst_path)
        src = os.path.join(root,i file)
        dst = os.path.join(dst_path, file)
        shutils.copyfile(srd, dst)

答案 2 :(得分:1)

这可能对您有用:

a=/mysql/data
sed 's|.*\(/[^/]*/[^/]*\)|mv -v & '"$a"'\1|' file 
mv -v /path/to/file/is/abc.txt /mysql/data/is/abc.txt
mv -v /another/file/is/here/xyz.txt /mysql/data/here/xyz.txt

研究输出,如果一切正常,则运行:

sed 's|.*\(/[^/]*/[^/]*\)|mv -v & '"$a"'\1|' file | bash

答案 3 :(得分:0)

如果要先复制文件,则需要为其创建目录。您可以使用单个查找命令来执行此操作,但我不确定此解决方案的效率?

#!/bin/bash
# $1 - destination

find $1 -type f -exec bash -c '
  dest="$2";                            # $2 is second argument passed to the script
  dir=$(basename $(dirname $1));        
  mkdir $dest/$dir 2>/dev/null;        
  cp $1 "$dest/$dir/";                  
' -- {} $2 \;                           # {} = $1 in bash '..' and $2=$2

用法:./ copy copy_from copy_to

编辑: 看起来更好:

#!/bin/bash

dest=$2
from=$1

# copy_file from dest
copy_file() {
 dir=$(basename $(dirname $from))
 mkdir $dest/$dir
 cp $from $dest/$dir
}

find $from -type f | while read file; do copy_file $file $dest; done