【问题标题】:Using xargs command and two move commands following it使用 xargs 命令和其后的两个移动命令
【发布时间】:2012-07-13 09:27:21
【问题描述】:

操作系统:aix 外壳:bsh

大家好

我有两种类型的文件,一种以 .pdf.marker 结尾,另一种以 .pdf

结尾

应该总是有一对同名的(只是扩展名不同)。

当我移动 .pdf.marker 文件时,我还必须移动其对应的 .pdf 文件。

我尝试过这样的事情:

find ${INPUT_LOCATION}/ -name "*.pdf.marker" | xargs -I file mv file ${OUTPUT_LOCATION}/. mv $(basename file .marker) ${OUTPUT_LOCATION}/. 

然后我读到:xargs with multiple commands as argument 并尝试了这样的事情:

find ${INPUT_LOCATION}/ -name "*.pdf.marker" | xargs -I file {mv file ${OUTPUT_LOCATION}/.; mv $(basename file .marker) ${OUTPUT_LOCATION}/.;} 

但还是不行。

我只需要在 xargs 之后执行 2 个命令。

编辑

按照我得到的建议答案,我尝试将 2 个参数放入一个移动命令中 而不是 xargs 之后的两个单独的移动命令。

find ${INPUT_LOCATION}/ -name "*.pdf.marker" | xargs -I file mv file $(basename file .marker) ${OUTPUT_LOCATION}/. 

但是现在,首先移动 .pdf.marker,然后当我尝试从文件名中删除 .marker 以获取 .pdf 文件名我收到警告没有这样的文件或目录。

还有其他方法可以获取 .pdf 文件名字符串吗?

解决方案

find ${INPUT_LOCATION} -name '*.pdf.marker' -exec sh -c 'mv $0 `dirname $0`/`basename $0 .marker` $1' {} ${OUTPUT_LOCATION} \;

在 cca 中移动了 200 000 个文件。 25 分钟。没有问题。

感谢所有参与并提供答案的人,非常感谢你 Nahuel Fouilleul!

【问题讨论】:

    标签: bash xargs


    【解决方案1】:

    您可以尝试以下方法:

    find ${INPUT}/ -name "*.pdf" -exec mv '{}' '{}'.marker ${OUTPUT} \;
    

    要测试标记文件是否存在,您可以使用以下内容:

    find ${INPUT}/ -name "*.pdf" -exec test -e '{}'.marker \; -exec mv '{}' '{}'.marker ${OUTPUT} \;
    

    【讨论】:

    • 只有在 .pdf.marker 文件存在且仅在那时才允许移动 .pdf 文件。所以我需要在 .pdf.marker 文件上使用 basename 命令
    • 我更新了我的答案,现在只会移动带有标记文件的 pdf 文件。
    【解决方案2】:

    试试这个(调试的 x 选项)

    find "${INPUT_LOCATION}" -name '*.pdf.marker' | xargs -i bash -cx 'pdf=`dirname {}`/`basename {} .marker`;[ -e "$pdf" ]&&{ mv {} "$pdf" "$0";}' "${OUTPUT_LOCATION}"
    

    或更短

    find $INPUT_LOCATION -name '*.pdf.marker' | xargs -i bash -c 'mv ${0%.marker} $0 $1' {} $OUTPUT_LOCATION
    

    find $INPUT_LOCATION -name '*.pdf.marker' -exec bash -c 'mv ${0%.marker} $0 $1' {} $OUTPUT_LOCATION \;
    

    也许更标准

    find ${INPUT_LOCATION} -name '*.pdf.marker' -exec sh -c 'mv $0 `dirname $0`/`basename $0 .marker` $1' {} ${OUTPUT_LOCATION} \;
    

    并且可以添加测试回声

    find ${INPUT_LOCATION} -name '*.pdf.marker' -exec sh -c 'echo mv $0 `dirname $0`/`basename $0 .marker` $1' {} ${OUTPUT_LOCATION} \;
    

    【讨论】:

    • 你的中间答案对我有用。谢谢 :) 我还有一个问题,也许你会知道;该脚本在 aix 下运行并将通过 bsh 执行,...xargs -i bash -c 'mv... . 制造问题?在我的测试环境中我有 bash 但在生产环境(我被禁止访问)它的 bsh
    • 变量替换 ${VAR%pat} 可能不适用于 bsh,因此第一个答案是更标准的 sh 但可能使用 -f 而不是 -e
    • 第四个(更标准的版本)说 find missing argument '-exec'
    • 是的,即使是 25k 文件,它也能很好地工作,但它不再使用 xargs。我可能会使用你的版本,但我必须小心,因为当我们使用 ls 命令与没有 xargsfor 循环 结合使用时,我们得到了一个对于大量文件 cca,参数列表太长等错误。 15k
    • ls 的问题是 * 的 shell 扩展,find 不是这种情况,因为 * 在引号之间没有 shell 扩展来查看 echo '*.pdf.marker'echo *.pdf.marker 的区别
    【解决方案3】:

    无需使用 xargs:

    for i in `find ${INPUT_LOCATION} -name \*.pdf`; do mv $i ${OUTPUT_LOCATION}; mv $i.marker ${OUTPUT_LOCATION}; done
    

    【讨论】:

    • 我需要 xargs 因为 find 返回 >30k 文件名
    【解决方案4】:
    for f in *.pdf.marker; do
      if [ -e "${f%.marker}" ]; then
        mv "$f" "${f%.marker}" "$OUTPUT_LOCATION"
      fi
    done
    

    【讨论】:

      【解决方案5】:

      如果您安装了 GNU Parallel:

      find ${INPUT_LOCATION} -name '*.pdf.marker' | parallel mv {} {.} ${OUTPUT_LOCATION}
      

      要了解更多信息,请观看介绍视频:http://pi.dk/1

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-19
        • 2016-08-06
        • 2011-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多