在终端中将文件重命名为父目录的名称

DTR*_*DTR 7 command-line bash

我必须处理嵌套在目录中的大量文件(每个目录一个文件),类似于以下内容:

fred/result.txt
john/result.txt
mary/result.txt
...
Run Code Online (Sandbox Code Playgroud)

我目前正在使用以下命令来处理每个文件:

find . -maxdepth 1 -type d \( ! -name . \) -exec bash -c \"cd '{}' && processResult result.txt\" \;
Run Code Online (Sandbox Code Playgroud)

我正在寻找可以添加到此命令末尾的内容,将文件名更改为fred.txt等,然后将文件移动到父目录中以消除额外的目录层。

什么是最好的方法来做到这一点?

ste*_*ver 7

我认为这是合法的(使用基于 perl 的rename命令)

\n\n
find dir -name 'results.txt' -exec rename -nv -- 's|/(.*)/(.*)$|/$1/$1.txt|' {} +\n
Run Code Online (Sandbox Code Playgroud)\n\n

例如给定

\n\n
$ tree dir\ndir\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 fred\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 results.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 john\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 results.txt\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 mary\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 results.txt\n\n3 directories, 3 files\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后

\n\n
$ find dir -name 'results.txt' -exec rename -v -- 's|/(.*)/(.*)$|/$1/$1.txt|' {} +\ndir/fred/results.txt renamed as dir/fred/fred.txt\ndir/john/results.txt renamed as dir/john/john.txt\ndir/mary/results.txt renamed as dir/mary/mary.txt\n
Run Code Online (Sandbox Code Playgroud)\n\n

导致

\n\n
$ tree dir\ndir\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 fred\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 fred.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 john\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 john.txt\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 mary\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 mary.txt\n\n3 directories, 3 files\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

如果您只需要低于 1 级dir,您也许可以简单地执行以下操作

\n\n
rename -vn -- 's|/(.*)/(.*)$|/$1/$1.txt|' dir/*/results.txt\n
Run Code Online (Sandbox Code Playgroud)\n\n

与往常一样,该-n选项保留用于测试目的

\n


Jac*_*ijm 5

下面的小python脚本将完全按照您的描述进行;它会:

  • results.txt根据其上级目录重命名给定目录中的任何文件,命名为
  • 将其向上移动一级(目录)
  • 删除文件最初所在的(现在是空的)目录

结果:

这个:

directory
|
??? fred
?   ??? results.txt
??? john
?   ??? results.txt
??? mary
    ??? results.txt
Run Code Online (Sandbox Code Playgroud)

会变成:

directory
|
??? fred.txt
?   
??? john.txt
? 
??? mary.txt
Run Code Online (Sandbox Code Playgroud)

剧本

directory
|
??? fred
?   ??? results.txt
??? john
?   ??? results.txt
??? mary
    ??? results.txt
Run Code Online (Sandbox Code Playgroud)

使用

  • 将下面的代码复制到一个空文件中,另存为 move_rename.py
  • 通过以下命令运行它:

    python3 /path/to/move_rename.py <directory_to_reorganize>
    
    Run Code Online (Sandbox Code Playgroud)

笔记

一如既往,先在小样本上进行测试


Ser*_*nyy 5

我们可以使用经典方法:findwhile read 组合:

演示:

$ ls *
fred:
results.txt

jane:
results.txt

john:
results.txt

$> find . -type f -name "results.txt" -printf "/%P\n" | while read FILE ; do DIR=$(dirname "$FILE" );\                            
>  mv ."$FILE" ."$DIR""$DIR".txt;done                                                                                             
$> ls
fred/  jane/  john/
$> ls *
fred:
fred.txt

jane:
jane.txt

john:
john.txt
Run Code Online (Sandbox Code Playgroud)

在使用echo之前使用mv来测试您的文件的行。

小改进

我们可以将调用嵌入bash到 exec 中,并带有参数扩展(特别是去除前缀)。基本上它是将脚本嵌入到 exec 调用中。

$> find "$PWD" -type f -name "results.txt" -exec bash -c ' DIR=$( dirname "{}"  ); echo "{}" "$DIR"/"${DIR##*/}".txt  ' \;                
/home/xieerqi/TESTDIR/fred/results.txt /home/xieerqi/TESTDIR/fred/fred.txt
/home/xieerqi/TESTDIR/jane/results.txt /home/xieerqi/TESTDIR/jane/jane.txt
/home/xieerqi/TESTDIR/john/results.txt /home/xieerqi/TESTDIR/john/john.txt
Run Code Online (Sandbox Code Playgroud)

为了使命令通用,(适用于任何文件,而不仅仅是results.txt)只需删除-name "results.txt"部分。另请参阅这篇文章,了解对此的替代 Python 解决方案。