【问题标题】:Copying list of files to a directory将文件列表复制到目录
【发布时间】:2014-01-03 08:04:10
【问题描述】:

我想搜索名称中包含特定文本的所有 .fits 文件,然后将它们复制到一个目录中。

我可以使用一个名为 fetchKeys 的命令来列出包含 say 'foo' 的文件

命令如下所示:fetchKeys -t 'foo' -F | grep .fits

这将返回包含“foo”的 .fits 文件列表。伟大的!现在我想将所有这些复制到一个目录/path/to/dir。需要单独处理的文件太多,我需要使用一个命令将它们全部复制。

我在想这样的事情:

fetchKeys -t 'foo' -F | grep .fits > /path/to/dir

cp fetchKeys -t 'foo' -F | grep .fits /path/to/dir

当然,这些都不起作用。还有其他想法吗?

【问题讨论】:

    标签: bash copying


    【解决方案1】:

    xargs 工具可以针对从标准输入获取的每一行执行命令。这一次,我们执行cp 命令:

    fetchkeys -t 'foo' -F | grep .fits | xargs -P 1 -n 500 --replace='{}' cp -vfa '{}' /path/to/dir
    

    xargs 是一个非常有用的工具,尽管它的参数化并不是很简单。该命令读取 500 个 .fits 文件,并为每个组调用一个 cp 命令。我没有深入测试它,如果它不去,我正在等待你的评论。

    【讨论】:

    • 感谢您的回复。抱歉,我在两个 '{}' 中放了什么?我假设我会将 /path/to/dir 放入其中之一。还有916个文件要复制。谢谢。
    • 没什么,应该输入。
    • 嗨,彼得。糟糕,我没有向右滚动,我没有看到 /path/to/dir 。好的,我运行了命令,它现在正在运行,所以谢谢你。看起来可能需要一段时间,所以我会在完成时通知您。另外,如果你有时间,你知道是否有办法将文件复制到另一台服务器:类似 :scp fetchKeys -t 'foo' | grep .fits me@123.456.789:/path/to/dir ?再次感谢。
    • @Derek 如果你高兴,你为什么不接受/赞成我的回答?
    • 刚刚接受了您的回答,但不能投票给您,因为我需要 15 声望才能做到这一点。
    【解决方案2】:

    如果这是在 Linux/Unix 上,你可以使用find 命令吗?这看起来很像fetchkeys

    $ find . -name "*foo*.fit" -type f -print0 | while read -r -d $'\0' file
    do
        basename=$(basename $file)
        cp "$file" "$fits_dir/$basename"
    done
    

    find 命令将查找名称中与*foo*.fits 匹配的所有文件。 -type f 说它们必须是文件而不是目录。 -print0 表示打印找到的文件,但用NUL 字符分隔它们。通常情况下,find 命令只会在每一行返回一个文件,但如果文件名包含空格、制表符、换行符,甚至是其他奇怪的字符怎么办?

    -print0 将用空字符 (\0) 分隔出文件,read -d $'\0' file 表示读取由这些空字符分隔的每个文件。如果您的文件不包含空格或奇怪字符,您可以这样做:

    $ find . -name "*foo*.fit" -type f | while read file
    do
        basename=$(basename $file)
        cp "$file" "$fits_dir/$basename"
    done
    

    基本上,您将使用 find 命令找到的每个文件读入 shell 变量 file。然后,您可以使用该文件将该文件复制到您的 $fits_dir 或您想要的任何位置。

    同样,也许有使用fetchKeys 的理由,并且可以将find 替换为fetchKeys,但我不知道fetchKeys 命令。

    【讨论】:

    • 感谢您的回复。是的,它是 Linux,我正在 ssh 登录到可以使用此 fetchKeys 命令的另一台服务器。我对它了解不多,它也没有“人”。抱歉,我犯了一个错误,文件名中不存在“foo”,它是我假设在 fit 文件中某处声明的对象的名称。所以 fetchKeys 将首先从 fit 文件中找到所有名为 'foo' 的对象,然后我使用 grep 来挑选出 fit 文件。所以我不能在这里使用 find 。有 916 个文件要复制。有什么想法吗?
    • 您可以使用 fetchKeys -t 'foo' -F | grep .fits 并将其传递给 while read 命令。基本上,您需要将要复制的文件提供到您进行备份的位置。
    • read -d $'\0' 可以简化为read -d ''
    【解决方案3】:

    将名称中包含foo的所有文件复制到某个目录下:

    find . -name "*foo*.fit" -type f -exec cp {} "/path/to/dir/" \; 
    

    将所有包含foo的文件本身复制到某个目录下(不带xargs的解决方案):

    for f in `find . -type f  -exec grep -l foo {} \;`; do cp "$f" /path/to/dir/; done
    

    find 命令具有非常有用的参数-exec-print-delete。它们非常健壮,无需手动处理文件名。 -exec 的语法是:-exec (what to do) \;。当前处理的文件的名称将被替换,而不是占位符{}

    对此类任务非常有用的其他命令是 sedawk

    【讨论】:

    • 对不起,我弄错了,'foo' 不存在于文件名中,它存在于 fit 文件本身中。它是对象的名称。所以我需要使用这个 fetchKeys 命令。我绝对不能在这里使用 find 来挑出这些文件。还有其他想法吗?谢谢。
    • 当然,也为此添加了解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-20
    • 2010-11-19
    • 1970-01-01
    • 2012-03-18
    相关资源
    最近更新 更多