linux 如何在多个目录之间重命名名称一致的子目录?

w6lpcovy  于 2022-12-03  发布在  Linux
关注(0)|答案(5)|浏览(219)

我想重命名

123/1/ -> 123/v1/
foo/1/ -> foo/v1/
bar/1/ -> bar/v1/
345/1/ -> 345/v1/

我已经搜索并找到了一些相关的解决方案,但不太确定在这种情况下什么是最好的。例如,

find . -wholename "*/1" -exec echo '{}' \;

成功地打印出了所有相对于.的路径,但是{}扩展到./foo/1/,所以我不能从{}移动到{}/v1

find . -wholename "*/1" -exec mv '{}' $(echo '{}' | sed 's/1/v1/') \;

我的想法是调用mv ./foo/1 ./foo/v1,但显然它试图将.foo/1/移动到它自己的子目录中。
总之,我只是想寻找一种最简单的方法来进行批量重命名。为了清楚起见,我试图将文本子目录1移动到v1,而不是将2移动到v2

gkl3eglg

gkl3eglg1#

像这样,使用perl rename(它可能与系统中已经存在的rename不同,使用rename --version进行检查):

rename -n 's|([^/]+/)(1)|$1v$2|' */1/

当输出适合您时,删除-n(空运行)。
(note您可以在bash上使用globstar或在其他shell上使用类似的方法递归到更深的子目录中)

gzszwxb4

gzszwxb42#

类似这样的东西,未经测试,IMHO是最简单的方法,只要你的路径不包含换行符,使用bash内置程序和强制的POSIX实用程序:

while IFS= read -r old; do
    new="${old##*/}v1"
    echo mv -- "$old" $new"
done < <(find . -type d -name 1)

如果您对初始测试的输出满意,请删除echo

kuhbmx9i

kuhbmx9i3#

这是用鱼做的标签。一个用鱼壳做的解决方案:

for file in **/1/; mv $file (dirname $file)/v1; end
nqwrtyyt

nqwrtyyt4#

尝试

find . -depth -type d -name 1 -execdir mv 1 v1 \;
u0sqgete

u0sqgete5#

我会直接用巴什来做。
给定:

$ tree .
.
├── 123
│   └── 1
├── 345
│   └── 1
│       └── 1        # this is a file named '1'
├── bar
│   └── 1
└── foo
    └── 1
        └── file
8 directories, 2 files

您可以:

#!/bin/bash

shopt -s globstar
new_1="v1"

for src in **/*/1; do      # will RECURSIVELY find any directory '1'
                           # if just next level (as in example)
                           # you can just do */1
    [ -d "$src" ] || continue 
    tgt="${src%%/1}/$new_1"
    echo "./$src/ => ./$tgt/"
    mv  "./$src" "./$tgt/"
done

结果:

$ tree .
.
├── 123
│   └── v1
├── 345
│   └── v1
│       └── 1
├── bar
│   └── v1
└── foo
    └── v1
        └── file
 8 directories, 2 files

如果要插入父目录,请添加一条语句来创建它们:

shopt -s globstar
new_1="a parent/v1"         # the replacement path has a parent

for src in **/*/1; do 
    [ -d "$src" ] || continue 
    tgt="${src%%/1}/$new_1"
    [[ "/" == *"$new_1"* ]] || mkdir -p "${tgt%/*}"  # create parents if any
    echo "./$src/ => ./$tgt/"
    mv  "./$src" "./$tgt/"
done

结果:

$ tree .
.
├── 123
│   └── a parent
│       └── v1
├── 345
│   └── a parent
│       └── v1
│           └── 1
├── bar
│   └── a parent
│       └── v1
└── foo
    └── a parent
        └── v1
            └── file
 12 directories, 2 files

相关问题