将文件移动到当前位置的父目录
Move files to parent directory of current location
我有很多文件夹,里面有一个文件夹,里面有文件。我想将第 2 级文件移动到第 1 级,并且不知道它们的名称。
简单示例:
在运行一个脚本之前:
/temp/1stlevel/test.txt
/temp/1stlevel/2ndlevel/test.rtf
在运行一个脚本之后:
/temp/1stlevel/test.txt
/temp/1stlevel/test.rtf
我已经很接近了,但我遗漏了一些东西,我确定是 simple/stupid。这就是我 运行:
find . -mindepth 3 -type f -exec sh -c 'mv -i "" "${1%/*}"' sh {} \;
这就是我的灵感:
mv: './1stlevel/2ndlevel/test.rtf' and './1stlevel/2ndlevel/test.rtf' are the same file
有什么建议吗?
更新:乔治,这是很棒的东西,谢谢!我学到了很多东西并做笔记。使用 mv
命令而不是更复杂的命令非常棒。我已经不是第一次被指责以最艰难的方式做事了!
但是,虽然它适用于一组文件夹,但如果我有更多文件夹,它就无法按预期工作。这就是我的意思:
之前:
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
- 不过我不需要花哨,因为稍后在我的脚本中我只是删除空文件夹。
顺便说一句,我花了很长时间才在 Notepad++ 中画画。你用的是什么?
mv YOUR-FILE-NAME ../
如果你有写权限,我应该这样工作
我用这个例子来说明:
树结构:
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/
中的文件之后,那么您将从 temp 开始使用 -mindepth 3
访问它。请参阅:man find
。
现在对于我使用的目的地 ./*/*
,解释“从当前目录(从临时目录开始,我的是新目录)向下到 temp
,然后是 1stlevel
,所以:
./
: => 新建文件夹
./*
: => new/temp 文件夹
./*/*
: => new/temp/1stlevel
但所有这些都是针对 find
命令的,但另一个技巧是仅从 new
文件夹使用 mv
命令:
mv ./*/*/*/* ./*/*
这是 运行 来自我示例中的新文件夹(换句话说,来自临时文件夹上方的一个文件夹)。对其进行不同级别的调整运行。
从 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
你的find . -mindepth 3 -type f -exec sh -c 'mv -i "" "${1%/*}"' sh {} \;
尝试非常接近正确。
调试复杂命令时的有用技巧
就是插入echo
语句,看看发生了什么。
所以,如果我们说
$ find . -mindepth 3 -type f -exec sh -c 'echo mv -i "" "${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%/*}/.."' 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%/*/*}"' 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
删除空的 SubFolder<i>N</i>
目录。
如果由于某种故障,它们中的任何一个都不为空,
find
将保留它并发出警告消息。
让您的脚本导航到您需要移动文件的每个目录 "up," 然后您可以 find
找到目录中的每个文件,然后将它们向上移动一个目录:
$ find . -type f -exec mv {} ../. \;
我有很多文件夹,里面有一个文件夹,里面有文件。我想将第 2 级文件移动到第 1 级,并且不知道它们的名称。
简单示例:
在运行一个脚本之前:
/temp/1stlevel/test.txt /temp/1stlevel/2ndlevel/test.rtf
在运行一个脚本之后:
/temp/1stlevel/test.txt /temp/1stlevel/test.rtf
我已经很接近了,但我遗漏了一些东西,我确定是 simple/stupid。这就是我 运行:
find . -mindepth 3 -type f -exec sh -c 'mv -i "" "${1%/*}"' sh {} \;
这就是我的灵感:
mv: './1stlevel/2ndlevel/test.rtf' and './1stlevel/2ndlevel/test.rtf' are the same file
有什么建议吗?
更新:乔治,这是很棒的东西,谢谢!我学到了很多东西并做笔记。使用 mv
命令而不是更复杂的命令非常棒。我已经不是第一次被指责以最艰难的方式做事了!
但是,虽然它适用于一组文件夹,但如果我有更多文件夹,它就无法按预期工作。这就是我的意思:
之前:
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
- 不过我不需要花哨,因为稍后在我的脚本中我只是删除空文件夹。
顺便说一句,我花了很长时间才在 Notepad++ 中画画。你用的是什么?
mv YOUR-FILE-NAME ../
如果你有写权限,我应该这样工作
我用这个例子来说明:
树结构:
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/
中的文件之后,那么您将从 temp 开始使用 -mindepth 3
访问它。请参阅:man find
。
现在对于我使用的目的地 ./*/*
,解释“从当前目录(从临时目录开始,我的是新目录)向下到 temp
,然后是 1stlevel
,所以:
./
: => 新建文件夹./*
: => new/temp 文件夹./*/*
: => new/temp/1stlevel
但所有这些都是针对 find
命令的,但另一个技巧是仅从 new
文件夹使用 mv
命令:
mv ./*/*/*/* ./*/*
这是 运行 来自我示例中的新文件夹(换句话说,来自临时文件夹上方的一个文件夹)。对其进行不同级别的调整运行。
从 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
你的find . -mindepth 3 -type f -exec sh -c 'mv -i "" "${1%/*}"' sh {} \;
尝试非常接近正确。
调试复杂命令时的有用技巧
就是插入echo
语句,看看发生了什么。
所以,如果我们说
$ find . -mindepth 3 -type f -exec sh -c 'echo mv -i "" "${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%/*}/.."' 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%/*/*}"' 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
删除空的 SubFolder<i>N</i>
目录。
如果由于某种故障,它们中的任何一个都不为空,
find
将保留它并发出警告消息。
让您的脚本导航到您需要移动文件的每个目录 "up," 然后您可以 find
找到目录中的每个文件,然后将它们向上移动一个目录:
$ find . -type f -exec mv {} ../. \;