展平文件夹结构


8

我有这个文件夹结构:

├── foo1
   ├── bar1.txt
   └── bar2.txt
├── foo2
   ├── bar3.txt
   └── bar4 with a space.txt
└── foo3
    └── qux1
        ├── bar5.txt
        └── bar6.txt

我想在每个文件夹级别之间加一个下划线:

├── foo1_bar1.txt
├── foo1_bar2.txt
├── foo2_bar3.txt
├── foo2_bar4 with a space.txt
├── foo3_qux1.bar6.txt
└── foo3_qux1_bar5.txt

我四处张望,没有找到任何可行的解决方案,主要是因为我的问题有两个特殊之处:根目录中可能存在多个文件夹级别,而且某些文件可能包含空格。

任何想法如何在bash中完成此操作?谢谢!

编辑:运行格连杰克曼建议答案我得到这个:

在此处输入图片说明

一级文件夹有两个下划线。知道如何避免这种情况或只是对其重命名,以便仅使用一个下划线吗?谢谢。

Answers:


15
find */ -type f -exec bash -c 'file=${1#./}; echo mv "$file" "${file//\//_}"' _ '{}' \;

echo如果满意,请删除。不必担心echo'ed命令不会显示引号,该脚本将正确处理带有空格的文件。

如果要删除现在空的子目录:

find */ -depth -type d -exec echo rmdir '{}' \; 

嘿。棒极了!谢谢。那几乎完全做到了。我只是遇到一个小问题,即foo1__qux1_bar5.txt在第一个文件夹级别中有两个下划线。尝试弄乱您的bash行,但似乎无济于事。也许我需要添加一些内容?
nunos 2015年

@nunos,我无法重现该行为
glenn jackman

真?奇怪的。我刚刚用更多信息更新了答案。你能看看吗?谢谢。
nunos 2015年

1
嗯 好,更改"${file//\//_}""${file//+(/)/_,如果这是一个脚本,shopt -s extglob
glenn jackman

我也有两个下划线的问题。不幸的是,按照您的建议更改命令对我不起作用。我确实在AskDifferent上找到了这个答案:apple.stackexchange.com/a/254224/122152 根据答案,macOS可能正在使用BSD查找。解决方法是使用findutils。可以使用homebrew with进行安装brew install findutils,然后使用gfind代替find。这对我有用。
intagli

5

使用perl的重命名:

find . -depth -type f -exec rename 's@(?<!\.)/@_@g' -- {} \;

输出值

$ find -type f
./foo2_bar4 whit a space.txt
./foo3_qux1_bar6.txt
./foo2_bar3.txt
./foo3_qux1_bar5.txt
./foo1_bar2.txt
./foo1_bar1.txt

注意

  • 我用消极的眼神 (?<!\.)不碰第一个./
  • 我保留空的目录,请随意:

    find . -depth -type d -exec rm {} \;

警告 还有其他相同名称的工具可能无法执行此操作,因此请小心。

如果运行以下命令(GNU

$ file "$(readlink -f "$(type -p rename)")"

结果是

.../rename: Perl script, ASCII text executable

并且不包含:

ELF

那么这似乎是正确的工具=)

如果不是,则将其设为默认值(通常已经是这种情况),Debian并派生为Ubuntu

$ sudo update-alternatives --set rename /path/to/rename

(替换/path/to/renameperl's rename命令的路径。


如果您没有此命令,请搜索软件包管理器以进行安装或手动执行


最后但并非最不重要的一点是,该工具最初由Perl的父亲Larry Wall编写。


... -type d -exec rmdir ...?
JJoao 2015年

我似乎没有可用的重命名。.我究竟如何获得它,并且它在UNIX系统中通常可用吗?谢谢。
nunos 2015年

@nunos这是一个Perl脚本。它可以perl-rename在Arch Linux和prename基于Debian的系统中使用。
muru

新增rename说明
Gilles Quenot 2015年

1

pax...

pax -Xrwls '|/|_|g' */ "$PWD"

这将在当前目录中创建一个到其子目录中所有文件的硬链接,并用_代替/。然后,您可以检查结果并使用...删除所有子目录。

rm -rf */

...一旦您验证了结果符合您的喜好。


0

您可以尝试以下命令。

$ find -type f -exec bash -c 'mv $0 $(echo $0|sed "s/\//_/2")' {} \;

上面的命令将移动文件,目录将保留,以后可以删除。

$ ls
foo1_bar1.txt  foo1_bar2.txt  foo2_bar3.txt  foo2_bar4.txt  foo3_bar5.txt  foo3_bar6.txt
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.