提问人:Terry Bishop 提问时间:11/9/2023 最后编辑:Terry Bishop 更新时间:11/10/2023 访问量:83
使用 find、sed 和 mv 递归查找和删除子目录名称中的字符
Find and remove a character in subdirectory names recursively with find, sed and mv
问:
我正在尝试递归删除子目录中的字符,但似乎无法确定正确答案。我正在运行 BSD,并希望使用 find、sed 和 mv 来实现这一点。我是脚本编写和使用 sed 的初学者,因此任何帮助将不胜感激。
我在不同的子目录中命名了目录
dir/foobar 01
foobar 02
foobar 03
dir2/foobar 01
foobar 02
foobar 03
我想删除每个目录名称中的 0
dir/foobar 1
foobar 2
foobar 3
dir2/foobar 1
foobar 2
foobar 3
我已经通过 find 和 sed 走到了这一步,但不知道如何合并 mv 命令
find . -type d -name "foobar 01" | sed 's/0//g'
这会打印正确的格式化,但没有 mv 命令,它不会做任何进一步的事情......
有没有办法对所有匹配的子目录使用一个命令来做到这一点,或者我必须单独处理每种情况?
谢谢。
答:
为此,您可以结合使用 find、sed 和 xargs 以递归方式重命名目录。
像这样的东西应该可以完成工作:
find . -type d -name "foobar 01" -print0 | xargs -0 -I {} sh -c 'mv "{}" "$(echo "{}" | sed "s/0//g")"'
以下是该命令的说明:
find . -type d -name "foobar 01" -print0
:这用于查找所有名为“foobar 01”的目录(),并使用空字符()打印它们。null 字符用于处理名称中包含空格的目录。-type d
-print0
xargs -0 -I {} sh -c '...'
:这将获取 (null 分隔的目录列表) 的输出,并将指定的命令应用于每个目录。是输入的占位符。find
{}
mv "{}" "$(echo "{}" | sed "s/0//g")"
:这是针对找到的每个目录执行的命令。它使用 mv 重命名目录。该命令用于从目录名称中删除“0”字符。sed
评论
希望我理解了你的问题,你有名为“foobar”的目录和子目录 01、02、03
以下是递归列出它们的方法:
for DIR in $(find . -maxdepth 2 -type d -name "*0*"); do echo "$DIR"; done
以下是处理后检查所需结果的方法:
for DIR in $(find . -maxdepth 2 -type d -name "*0*"); do echo "$DIR" | sed -E 's/0//g'; done
最后,这里是处理它们的命令:
for DIR in $(find . -type d -name "*0*"); do mv "$DIR" "$(echo "$DIR" | sed -E 's/0//g')"; done
enter code here
评论
既然你正在使用,你就可以使用递归球。zsh
鉴于:
% tree .
.
├── dir
│ ├── foobar 01
│ ├── foobar 02
│ ├── foobar 03
│ └── foobar 4
└── dir2
├── foobar 01
├── foobar 02
├── foobar 03
└── foobar 2
11 directories, 0 files
您可以使用此递归 glob 来查找名称中带有 的目录并重命名它们。这还会测试重命名是否会擦除现有文件或目录:0
#!/bin/zsh
# ^ that path deponds on your system.
for fn in **/*0[0-9]*/; do
nfn="${fn//0}"
if [[ -e $nfn ]]; then
echo "$nfn already exists! NOT renaming $fn=>$nfn"
continue
fi
echo "renaming: $fn=>$nfn"
mv "$fn" "$nfn"
done
结果:
% tree .
.
├── dir
│ ├── foobar 1
│ ├── foobar 2
│ ├── foobar 3
│ └── foobar 4
└── dir2
├── foobar 02
├── foobar 1
├── foobar 2
└── foobar 3
11 directories, 0 files
如果在循环上方添加,则相同的脚本适用于 Bash。shopt -s globstar
评论
zsh that_txt_file
上一个:如何创建自定义 ZSH 命令?
下一个:读取文本文件输出不正确的数据
评论
zmv
:autoload zmv; zmv '(dir*)/(foobar )0(*)' '$1/$2$3'