将文件夹内容递归到嵌套文件夹中

时间:2012-09-12 17:27:18

标签: linux bash unix gnu-coreutils

我不认为这会是一个问题。因为我认为coreutils支持这些东西然后,cp ls和rm的脏组合就足够了。

然而,事实并非如此,如果你现在解释我为什么我的approuch失败了,我将非常感激,并且我将如何以适当的方式做到这一点。

代码

function CheckoutFolder {
    local dir=$1


    mkdir "$dir/.CheckoutFolderTmp"
    (
        cd "$dir" \
        && cp -R $(ls -Q -A "$dir" --ignore=".CheckoutFolderTmp") "$dir/.CheckoutFolderTmp" \
        && rm -Rf  $(ls -Q -A "$dir" --ignore=".CheckoutFolderTmp")
    )
    mv "$dir/.CheckoutFolderTmp" "$dir/src"
    mkdir -p "$dir/"{build,log}
}

示例输出

++ CheckoutFolder /home/tobias/Develop/src/thelegacy/RCMeta
++ local dir=/home/tobias/Develop/src/thelegacy/RCMeta
++ mkdir /home/tobias/Develop/src/thelegacy/RCMeta/.CheckoutFolderTmp
++ cd /home/tobias/Develop/src/thelegacy/RCMeta
+++ ls -Q -A /home/tobias/Develop/src/thelegacy/RCMeta --ignore=.CheckoutFolderTmp
++ cp -R '"build"' '"buildmythli.sh"' '"CMakeLists.txt"' '".directory"' '".libbuildmythli.sh"' '"log"' '"RCMeta"' '"RCMetaTest"' '"src"' /home/tobias/Develop/src/thelegacy/RC
cp: cannot stat `"build"': No such file or directory
cp: cannot stat `"buildmythli.sh"': No such file or directory
cp: cannot stat `"CMakeLists.txt"': No such file or directory
cp: cannot stat `".directory"': No such file or directory
cp: cannot stat `".libbuildmythli.sh"': No such file or directory
cp: cannot stat `"log"': No such file or directory
cp: cannot stat `"RCMeta"': No such file or directory
cp: cannot stat `"RCMetaTest"': No such file or directory
cp: cannot stat `"src"': No such file or directory
++ mv /home/tobias/Develop/src/thelegacy/RCMeta/.CheckoutFolderTmp /home/tobias/Develop/src/thelegacy/RCMeta/src
++ mkdir -p /home/tobias/Develop/src/thelegacy/RCMeta/build /home/tobias/Develop/src/thelegacy/RCMeta/log
++ return 0

Mythli

2 个答案:

答案 0 :(得分:2)

正如Les所说,ls -Q在文件名周围加上引号,这些引号会在cprm的参数中传递。 (当您实际输入命令时,使用引号引用和分隔参数是Bash命令行的一个方面;当您将一个命令的输出传递给它时,它不起作用另一方面。)一般来说,解析ls的输出通常不是一个好主意。

这是另一种方法:

function CheckoutFolder() (
    cd "$1"

    mkdir .CheckoutFolderTmp

    find -mindepth 1 -maxdepth 1 -not -name .CheckoutFolderTmp \
         -exec mv {} .CheckoutFolderTmp/{} \;

    mv .CheckoutFolderTmp src

    mkdir build log
)

(注意我用括号(...)而不是花括号{...}包围了函数体。这导致整个函数在子shell中运行。)

答案 1 :(得分:1)

$(ls ...)命令会在名称周围添加不​​需要的引号。请考虑使用xargs和back-quotes。例如......

(cd "$dir" && cp -R `ls -Q -A "$dir" --ignore=".CheckoutFolderTmp"` "$dir/.CheckoutFolderTmp" && ls -Q -A "$dir" --ignore=".CheckoutFolderTmp" | xargs rm -Rf  )

cp输出不太友好,但确实提供了所需的信息。

cp:  cannot stat '"build"': No such file or directory

跳到最后声明“没有这样的文件或目录”。 “can not stat”含糊不清,但这意味着“cp”使用“stat”来获取有关它试图复制的文件或目录的一些信息。 “统计”失败了。它在名为“build”的文件(或目录)上的“没有这样的文件或目录”的errno失败了。那是因为,cp内部的实际参数是“build”(注意)引号),而你想要的文件名是build(注意没有引号)。

使用-Q调用$(ls ...)以引用引号(可能是为了处理带有空格和逗号以及其他违规字符的文件名)。但$(ls ......)已经为你报了。如果使用-0。

,xargs也可以处理时髦的文件名