我有很多文件夹里面有一个文件夹,里面有文件。我想将第二级文件移动到第一级,并且在不知道其名称的情况下这样做。
简单示例:
在运行脚本之前:
/temp/1stlevel/test.txt
/temp/1stlevel/2ndlevel/test.rtf
运行脚本后:
/temp/1stlevel/test.txt
/temp/1stlevel/test.rtf
我变得非常接近,但我错过了一些东西,我确信它很简单/愚蠢。这就是我正在运行的:
find . -mindepth 3 -type f -exec sh -c 'mv -i "$1" "${1%/*}"' sh {} \;
这就是我的意思:
mv: './1stlevel/2ndlevel/test.rtf' and './1stlevel/2ndlevel/test.rtf' are the same file
有什么建议吗?
更新:乔治,这很棒,谢谢!我正在学习很多并做笔记。使用mv
命令而不是更复杂的命令是很棒的。远非我第一次被指责以最艰难的方式做事!
然而,虽然它适用于1套文件夹,但如果我有更多,它不会按预期工作。这就是我的意思:
在:
new
└── temp
├── Folder1
│ ├── SubFolder1
│ │ └── SubTest1.txt
│ └── Test1.txt
├── Folder2
│ ├── SubFolder2
│ │ └── SubTest2.txt
│ └── Test2.txt
└── Folder3
├── SubFolder3
│ └── SubTest3.txt
└── Test3.txt
后:
new
└── temp
└── Folder3
├── Folder1
│ ├── SubFolder1
│ └── Test1.txt
├── Folder2
│ ├── SubFolder2
│ └── Test2.txt
├── SubFolder3
├── SubTest1.txt
├── SubTest2.txt
├── SubTest3.txt
└── Test3.txt
所需:
new
└── temp
├── Folder1
│ ├── SubFolder1
│ ├── SubTest1.txt
│ └── Test1.txt
├── Folder2
│ ├── SubFolder2
│ ├── SubTest2.txt
│ └── Test2.txt
└── Folder3
├── SubFolder3
├── SubTest3.txt
└── Test3.txt
如果有人想得到幻想*:
new
└── temp
├── Folder1
│ ├── SubTest1.txt
│ └── Test1.txt
├── Folder2
│ ├── SubTest2.txt
│ └── Test2.txt
└── Folder3
├── SubTest3.txt
└── Test3.txt
答案 0 :(得分:3)
您的find . -mindepth 3 -type f -exec sh -c 'mv -i "$1" "${1%/*}"' sh {} \;
尝试非常接近正确。
调试复杂命令时的一种有用技巧
是插入echo
语句来查看发生的情况。
所以,如果我们说
$ find . -mindepth 3 -type f -exec sh -c 'echo mv -i "$1" "${1%/*}"' sh {} \;,我们会得到
mv -i ./Folder1/SubFolder1/SubTest1.txt ./Folder1/SubFolder1
mv -i ./Folder2/SubFolder2/SubTest2.txt ./Folder2/SubFolder2
mv -i ./Folder3/SubFolder3/SubTest3.txt ./Folder3/SubFolder3
这非常有意义 - 它正在查找深度为3(及以上)的所有文件, 从路径名中删除最后一级,然后将文件移到那里。 但是,
mv (path_to_file) (path_to_directory)手段 将文件移动到目录中 所以命令
mv -i ./Folder1/SubFolder1/SubTest1.txt ./Folder1/SubFolder1
表示将Folder1/SubFolder1/SubTest1.txt
移至 Folder1/SubFolder1
-
但那就是它已经存在的地方。
因此,您收到错误消息说
您正在将文件移动到已经存在的位置。
从你的插图中可以清楚地看到,
您想将SubTest1.txt
移至Folder1
。
一个快速解决方法是
$ find . -mindepth 3 -type f -exec sh -c 'mv -i "$1" "${1%/*}/.."' sh {} \;
使用..
从SubFolder1
升级到Folder1
:
mv -i ./Folder1/SubFolder1/SubTest1.txt ./Folder1/SubFolder1/..
mv -i ./Folder2/SubFolder2/SubTest2.txt ./Folder2/SubFolder2/..
mv -i ./Folder3/SubFolder3/SubTest3.txt ./Folder3/SubFolder3/..
我相信那是不好的风格,虽然我无法弄明白为什么。 我更喜欢
$ find . -mindepth 3 -type f -exec sh -c 'mv -i "$1" "${1%/*/*}"' sh {} \;
使用%/*/*
从文件的路径名中删除两个组件
得到你真正想要的东西,
mv -i ./Folder1/SubFolder1/SubTest1.txt ./Folder1
mv -i ./Folder2/SubFolder2/SubTest2.txt ./Folder2
mv -i ./Folder3/SubFolder3/SubTest3.txt ./Folder3
然后您可以使用
$ find . -mindepth 2 -type d –delete
删除空的SubFolderN
目录。
如果由于某些故障,其中任何一个都不是空的,
find
将不理会并发出警告信息。
答案 1 :(得分:2)
让我用这个例子来说明:
树形结构:
new
└── temp
└── 1stlevel
├── 2ndlevel
│ └── text.rtf
└── test.txt
移动:
find . -mindepth 4 -type f -exec mv {} ./*/* \;
搬家后的结果:
new
└── temp
└── 1stlevel
├── 2ndlevel
├── test.txt
└── text.rtf
如果您从问题运行它,我从temp
文件夹中的一个文件夹运行,如果您想从temp
文件夹运行它,那么命令将是:
find 1stlevel/ -mindepth 2 -type f -exec mv {} ./* \;
或者:
find ./ -mindepth 3 -type f -exec mv {} ./* \;
请仔细查看find ./ -mindepth 3
部分,记住-mindepth 1 means process all files except the starting-points
。因此,如果您从temp
开始并且在temp/1st/2nd/
中的文件之后,那么您将使用-mindepth 3
从temp开始访问它。请参阅:man find
。
现在,对于我使用./*/*
的目的地,解释“从当前(一个从temp,我的是新的)目录下降到temp
,然后1stlevel
,所以:
./
:=>新文件夹./*
:=> new / temp文件夹./*/*
:=>新的/温度/ 1stlevel 但是find
命令的所有内容,但另一个技巧是仅使用mv
文件夹中的new
命令:
mv ./*/*/*/* ./*/*
这是从我的示例中的新文件夹运行的(换句话说,从temp文件夹中的一个文件夹)。进行调整以在不同级别运行它。
从temp
文件夹中运行:
mv ./*/*/* ./*
如果你提到你有很多文件,那么你的时间已经接近了,那么mv
选项会胜过find
选项。只查看三个文件的时间结果:
查找
real 0m0.004s
user 0m0.000s
sys 0m0.000s
MV:
real 0m0.001s
user 0m0.000s
sys 0m0.000s
由于OP想要一个脚本来访问我带来的多个文件夹:
#!/usr/bin/env bash
for i in ./*/*/*;
do
if [[ -d "$i" ]];
then
# Move the files to the new location
mv "$i"/* "${i%/*}/"
# Remove the empty directories
rm -rf "$i"
fi
done
./move.sh
运行,请记住使用chmod +x move.sh
使脚本可执行。目标目录结构:
new
├── move.sh
└── temp
├── folder1
│ ├── subfolder1
│ │ └── subtext1.txt
│ └── test1.txt
├── folder2
│ ├── subfolder2
│ │ └── subtext2.txt
│ └── test1.txt
└── folder3
├── subfolder3
│ └── subtext3.txt
└── test1.txt
获得花哨的结果:
new
├── move.sh
└── temp
├── folder1
│ ├── subtext1.txt
│ └── text1.txt
├── folder2
│ ├── subtext2.txt
│ └── text2.txt
└── folder3
├── subtext3.txt
└── text3.txt
答案 2 :(得分:0)
for( $i=0; $i<=10; $i++ )
{
if( $i%2 == 0 ){
echo $i;
}
}
如果你有写作权限,我会以这种方式工作
答案 3 :(得分:0)
让您的脚本导航到您需要移动文件的每个目录&#34; up,&#34;然后你可以find
找到目录中的每个文件,然后将它们移到一个目录中:
$ find . -type f -exec mv {} ../. \;