简体   繁体   English

将文件移动到当前位置的父目录

[英]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
  • I don't need to get fancy, though, 'cause later in my script I just remove empty folders. 不过,我不需要花哨的理由,因为稍后在脚本中,我只删除了空文件夹。

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 'echo mv -i "$1" "${1%/*}"' sh {} \;
we get 我们得到

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) mv (path_to_file)(path_to_directory) 
means move the file into the directory. 表示将文件移到目录中。
So the command 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

Update: 更新:

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

How to: Run from the new folder: ./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.

相关问题 如何通过*将包括隐藏文件在内的所有文件移动到父目录中 - How to move all files including hidden files into parent directory via * 显示当前目录而不是父目录中的所有隐藏文件 - display all hidden files in the current directory not in the parent directory linux将子文件夹中的文件移动到当前目录 - linux move files inside sub folder to current directory bash:将父目录下所有匹配的文件递归移动到新目录下 - bash: recursively move all matched files in sub directory of parent to new sub directory 将Maildir内容移到父目录 - Move Maildir contents to parent directory 如何在当前目录中查找以“ y”和“ .txt”结尾的文件(仅文件)并将其移动到其他文件夹? - How to find files (files only) with the ending 'y' and '.txt' in the current directory and move them to a different folder? 创建一个脚本,将所有 HTML 文件从当前工作目录复制到工作目录的父级 - Create a script that copies all the HTML files from the current working directory to the parent of the working directory Shell脚本,它将当前目录中的所有可执行文件移动到单独的文件夹中 - shell script which will move all executable files in the current directory to a seperate folder 在Bash中将文件从2个文本文件移动到位置 - In Bash move files to location, from 2 text files C++/C:将目录移动到另一个位置 - C++ / C: Move Directory to Another Location
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM