查找和向上移动文件一级


4

我正在尝试搜索具有特定扩展名的文件,然后将它们全部移动到文件夹层次结构中的一级。

基本上我有类似

/path/to/application/files/and/stuff/a1/nolongerneededirectory/*.*
/path/to/application/files/and/stuff/a2/nolongerneededirectory/*.*
/path/to/application/files/and/stuff/a3/nolongerneededirectory/*.*

我试图像这样将它们向上移动:

/path/to/application/files/and/stuff/a1/*.*
/path/to/application/files/and/stuff/a2/*.*
/path/to/application/files/and/stuff/a3/*.*

理想情况下,它将执行以下操作:

-bash-3.2$ find /path/to/ -name '*.txt'
output:
/path/to/directories1/test1/test1.txt
/path/to/directories2/test2/test2.txt
/path/to/directories3/test3/test3.txt

then 
mv /path/to/directories1/test1/test1.txt /path/to/directories1/test1.txt
mv /path/to/directories2/test2/test2.txt /path/to/directories2/test2.txt
mv /path/to/directories3/test3/test3.txt /path/to/directories3/test3.txt

我一直在尝试不同的选择,然后问周围,有人有什么想法吗?

编辑1:

所以我尝试了

`find /path/to/parent/dir -type f -exec mv {} .. \

但是我被拒绝了


好吧,我尝试了一下,find /path/to/dir -type f -exec sh -c 'mv -i "$1" "${1%/*}"' sh {} \;但最终得到了sh: bad substituion
Ideal2545 '20

是的,我不确定,在上周刚开始学习脚本时,是否可以澄清一下?
理想2545年

我从上面链接的内容中尝试了一个选项,但是在使用其他操作系统(本例中为Solaris 10)的情况下,出现了另一个错误。 find test -type f -exec mv {} .. \;输出mv: cannot rename test/test2/test3/test.jar to ../crap.jar: Permission denied
Ideal2545

是的,我看到了这个问题。因此,这会将文件相对于我执行命令的位置移动。我实际上想做的是将文件相对于文件上移一个级别。那有道理吗?
Ideal2545'4

啊对不起 我读错了。我链接到的帖子会将文件从您开始的位置移到父目录。您要将文件移动到其自己的父目录。删除了我的评论,因为它们已过时。
slhck 2012年

Answers:


1

如果您具有GNU find,则可以这样做(根据您的示例进行了修改):

find /path/to -type f -execdir mv {} .. \;

但是Solaris使用POSIX find作为标准,缺少此选项。不过,有时GNU工具可用(例如gfind)。

同样,-mindepth在这种情况下,仅返回给定最小目录深度的文件,此开关可能非常有用。


如果没有GNU find,请改用脚本:

#!/bin/sh
IFS='
'
for i in $(find /path/to -type f); do
    echo mv -- "${i}" "${i%/*/*}"
done

除非文件名包含换行符,否则它将起作用。首先按上述方式运行它,echo如果看起来还可以,请删除它(另请参见-mindepth上面的说明)。


while IFS= read -r -d '' file; do并且done < <(find /path/to -type f -print0)通常会达到相同的效果,并且完全安全,而不是for i in $(find…)
slhck 2012年

好的,我只是不喜欢介绍Bashisms,但有时它们确实有帮助。如果有人想这样做,请确保将更#!/bin/sh改为#!/bin/bash
丹尼尔·安德森

1

创建一个名为的脚本move_to_parent.sh,使其可执行。

#!/bin/bash

while [ $# -ge 1 ]
do
   parentPath=${1%/*/*};
   cp "$1" $parentPath;
   shift
done

有关参数替换的信息,请参见此处

这是move_to_parent.sh使用awk 进行书写的另一种方法-

#!/bin/bash

while [ $# -ge 1 ]
do
   echo $1 | awk -F/ '
             {
                parentPath="";

                for(loop=2;loop<NF-1;loop++)
                {
                   parentPath=parentPath"/"$loop;
                }
                sub(/\ /, "\ ", $0);
                system("mv " $0 " " parentPath );
             }'
   shift
done

运行如下-

find /path/to/parent/dir -iname "*.txt" | xargs  /path/to/scripts/move_to_parent.sh

或(未经测试,当心)find /path/to/parent/dir -iname "*.txt" -exec /path/to/scripts/move_to_parent.sh '{}' '+'
Eroen

您确定这适用于名称中带有空格或全角字符的文件吗?
slhck 2012年

可以在空间中正常工作
布莱恩2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.