[英]Move files to parent directory of current location
I have a lot of folders that have a folder inside them, with files inside. 我有很多文件夹,里面有一个文件夹,里面有文件。 I want to move the 2nd level files into the 1st level and do so without knowing their names.
我想将2级文件移到1级文件中,却不知道其名称。
Simple example: 简单的例子:
Before running a script: 在运行脚本之前:
/temp/1stlevel/test.txt /temp/1stlevel/2ndlevel/test.rtf
After running a script: 运行脚本后:
/temp/1stlevel/test.txt /temp/1stlevel/test.rtf
I'm getting very close but I'm missing something and I'm sure it's simple/stupid. 我离我很近,但是我错过了一些东西,我敢肯定这很简单/愚蠢。 Here's what I'm running:
这是我正在运行的:
find . -mindepth 3 -type f -exec sh -c 'mv -i "$1" "${1%/*}"' sh {} \;
Here's what that's getting me: 这就是给我的东西:
mv: './1stlevel/2ndlevel/test.rtf' and './1stlevel/2ndlevel/test.rtf' are the same file
Any suggestions? 有什么建议么?
UPDATE: George, this is great stuff, thank you! 更新:乔治,这是很棒的东西,谢谢! I'm learning a lot and taking notes.
我学到很多东西并做笔记。 Using the
mv
command instead of the more complicated one is brilliant. 使用
mv
命令而不是更复杂的命令是很不错的。 Far from the first time I've been accused of doing something the hardest way possible! 远非我第一次被指控以最困难的方式做某事!
However, while it works great with 1 set of folders, if I have more, it doesn't work as intended. 但是,虽然它可以很好地用于一组文件夹,但是如果我有更多文件夹,它将无法正常工作。 Here's what I mean:
这就是我的意思:
Before: 之前:
new
└── temp
├── Folder1
│ ├── SubFolder1
│ │ └── SubTest1.txt
│ └── Test1.txt
├── Folder2
│ ├── SubFolder2
│ │ └── SubTest2.txt
│ └── Test2.txt
└── Folder3
├── SubFolder3
│ └── SubTest3.txt
└── Test3.txt
After: 后:
new
└── temp
└── Folder3
├── Folder1
│ ├── SubFolder1
│ └── Test1.txt
├── Folder2
│ ├── SubFolder2
│ └── Test2.txt
├── SubFolder3
├── SubTest1.txt
├── SubTest2.txt
├── SubTest3.txt
└── Test3.txt
Desired: 期望:
new
└── temp
├── Folder1
│ ├── SubFolder1
│ ├── SubTest1.txt
│ └── Test1.txt
├── Folder2
│ ├── SubFolder2
│ ├── SubTest2.txt
│ └── Test2.txt
└── Folder3
├── SubFolder3
├── SubTest3.txt
└── Test3.txt
If one wanted to get fancy*: 如果想要花哨*:
new
└── temp
├── Folder1
│ ├── SubTest1.txt
│ └── Test1.txt
├── Folder2
│ ├── SubTest2.txt
│ └── Test2.txt
└── Folder3
├── SubTest3.txt
└── Test3.txt
BTW, that took me forever in Notepad++ to draw. 顺便说一句,这使我永远在Notepad ++中画画。 What did you use?
你用了什么?
Your find . -mindepth 3 -type f -exec sh -c 'mv -i "$1" "${1%/*}"' sh {} \\;
你的
find . -mindepth 3 -type f -exec sh -c 'mv -i "$1" "${1%/*}"' sh {} \\;
find . -mindepth 3 -type f -exec sh -c 'mv -i "$1" "${1%/*}"' sh {} \\;
attempt is very close to being right. 尝试非常接近正确。 A useful technique when debugging complex commands is to insert
echo
statements to see what is happening. 调试复杂命令时,一种有用的技术是插入
echo
语句以查看正在发生的情况。 So, if we say 所以,如果我们说
$ find . -mindepth 3 -type f -exec sh -c 'we getecho mv -i "$1" "${1%/*}"' sh {} \;
mv (path_to_file) (path_to_directory)
which makes perfect sense — it's finding all the files at depth 3 (and beyond), stripping the last level off the pathname, and moving the file there. 这非常有道理-查找深度3(及更高深度)的所有文件,从路径名中删除最后一层,然后将文件移到该位置。 But,
但,
mv (path_to_file) (path_to_directory)means move the file into the directory.mv (path_to_file)(path_to_directory)
mv -i ./Folder1/SubFolder1/SubTest1.txt ./Folder1/SubFolder1
means move Folder1/SubFolder1/SubTest1.txt
into Folder1/SubFolder1
— but that's where it already is.
mv -i ./Folder1/SubFolder1/SubTest1.txt ./Folder1/SubFolder1
意味着将Folder1/SubFolder1/SubTest1.txt
移至 Folder1/SubFolder1
-但这已经存在了。
Therefore, you got error messages saying that you were moving a file to where it already was.
As is clear from your illustration, you want to move SubTest1.txt
into Folder1
. 从插图中可以清楚地看到,您要将
SubTest1.txt
移至Folder1
。 One quick fix is 一种快速解决方法是
$ find . -mindepth 3 -type f -exec sh -c 'mv -i "$1" "${1%/*/*}"' sh {} \;
which uses ..
to go up from SubFolder1
to Folder1
: 它使用
..
从SubFolder1
转到Folder1
:
mv -i ./Folder1/SubFolder1/SubTest1.txt ./Folder1
mv -i ./Folder2/SubFolder2/SubTest2.txt ./Folder2
mv -i ./Folder3/SubFolder3/SubTest3.txt ./Folder3
I believe that that's bad style, although I can't figure out quite why. 我认为那是不好的风格,尽管我不知道为什么。 I would prefer
我会比较喜欢
$ find . -mindepth 2 -type d –delete
which uses %/*/*
to remove two components from the pathname of the file to get what you really want, 它使用
%/*/*
从文件的路径名中删除两个组件,以获得您真正想要的,
mv -i ./Folder1/SubFolder1/SubTest1.txt ./Folder1 mv -i ./Folder2/SubFolder2/SubTest2.txt ./Folder2 mv -i ./Folder3/SubFolder3/SubTest3.txt ./Folder3
You can then use 然后,您可以使用
$ find . -mindepth 2 -type d –delete
to delete the empty SubFolder N
directories. 删除空的
SubFolder N
目录。 If, through some malfunction, any of them is not empty, find
will leave it alone and issue a warning message. 如果由于某种故障,其中任何一个都不为空,则
find
会将其搁置并发出警告消息。
Let me use this example to illustrate: 让我用这个例子来说明:
Tree structure: 树形结构:
new
└── temp
└── 1stlevel
├── 2ndlevel
│ └── text.rtf
└── test.txt
Move with: 移动:
find . -mindepth 4 -type f -exec mv {} ./*/* \;
Result after move: 移动后的结果:
new
└── temp
└── 1stlevel
├── 2ndlevel
├── test.txt
└── text.rtf
Where you run it from matters, I am running from one folder up from the temp
folder, if you want to run it from the temp
folder then the command would be: 从问题上运行它的地方,我是从
temp
文件夹到一个文件夹,如果要从temp
文件夹运行,则命令将是:
find 1stlevel/ -mindepth 2 -type f -exec mv {} ./* \;
Or: 要么:
find ./ -mindepth 3 -type f -exec mv {} ./* \;
Please look closely at the section find ./ -mindepth 3
, remember that -mindepth 1 means process all files except the starting-points
. 请仔细查看
find ./ -mindepth 3
,请记住-mindepth 1 means process all files except the starting-points
。 So if you start from temp
and are after a file in temp/1st/2nd/
then you will access it with -mindepth 3
starting at temp. 因此,如果您从
temp
开始,并且位于temp/1st/2nd/
的文件之后,那么您将以-mindepth 3
从temp开始访问它。 Please see: man find
. 请参阅:
man find
。
Now for the destination I used ./*/*
, interpretation "from current (one up from temp, mine was new) directory down to temp
, then 1stlevel
, so: 现在,对于目的地,我使用了
./*/*
,解释为“从当前目录(从temp向上,我的是新的)到temp
,然后是1stlevel
,所以:
./
: => new folder ./
>新文件夹 ./*
: => new/temp folder ./*
>新/临时文件夹 ./*/*
: => new/temp/1stlevel ./*/*
>新/临时/ 1级 But all that is for the find
command but another trick is to use the mv
command only from the new
folder: 但是,对于
find
命令来说,所有的一切,但还有另一招,就是仅在new
文件夹中使用mv
命令:
mv ./*/*/*/* ./*/*
This is run from the new folder in my example (in other words from one folder up the temp folder). 在我的示例中,这是从新文件夹运行的(换句话说,是从temp文件夹的一个文件夹开始)。 Make adjustments to run it at different levels.
进行调整以在不同级别上运行它。
To run from the temp
folder: 要从
temp
文件夹运行:
mv ./*/*/* ./*
If your bordered about time since you mentioned you had a lot of files, then the mv
option beats the find
option. 如果自您提到您以来有时间限制,那么您有很多文件,那么
mv
选项将胜过find
选项。 See the time results for just three files: 仅查看三个文件的时间结果:
find: 找:
real 0m0.004s
user 0m0.000s
sys 0m0.000s
mv: MV:
real 0m0.001s
user 0m0.000s
sys 0m0.000s
Since OP wants a script to access multiple folders I came with this: 由于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
, remember to make the script executable with chmod +x move.sh
. ./move.sh
,请记住使用chmod +x move.sh
使脚本可执行。 Target directory structure: 目标目录结构:
new
├── move.sh
└── temp
├── folder1
│ ├── subfolder1
│ │ └── subtext1.txt
│ └── test1.txt
├── folder2
│ ├── subfolder2
│ │ └── subtext2.txt
│ └── test1.txt
└── folder3
├── subfolder3
│ └── subtext3.txt
└── test1.txt
Get fancy result: 获得理想的结果:
new
├── move.sh
└── temp
├── folder1
│ ├── subtext1.txt
│ └── text1.txt
├── folder2
│ ├── subtext2.txt
│ └── text2.txt
└── folder3
├── subtext3.txt
└── text3.txt
mv YOUR-FILE-NAME ../
如果您具有写权限,我应该以这种方式工作
让你的脚本导航到每个目录,你需要的文件移动“起来,”那么你可以有find
在目录中查找每个文件,然后将它们移到一个目录:
$ find . -type f -exec mv {} ../. \;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.