我有一个名为的目录assets
,它包含与此类似的文件结构:
├── a
│ ├── b
│ │ ├── c.png
│ │ └── d.png
│ └── b2
│ ├── e.png
│ ├── f.png
│ └── g.png
└── a2
└── b3
└── h.png
如何将此结构中的所有图像的名称更改为文件原始名称NAME_old.png
所在的模式? NAME
(例如,c.png
将更改为c_old.png
)
我有一种感觉,它与 sed/awk/grep 和使用管道有关,但我不知道如何使用这些工具,并且阅读文档并没有真正的帮助。
答案1
使用find
find assets -type d -exec sh -c '
for n in "$1"/*.png; do
test -f "$n" && mv "$n" "${n%.png}_old.png"
done' sh {} ';'
该find
命令寻找目录目录中或目录下assets
。对于每个找到的目录,它执行以下简短的 shell 脚本:
for n in "$1"/*.png; do
test -f "$n" && mv "$n" "${n%.png}_old.png"
done
where$1
将扩展为找到的目录的路径。该脚本将迭代*.png
目录中匹配的所有文件名,并使用变量替换.png
来替换文件名后缀。_old.png
这test -f
确保我们正在操作现有文件。这是需要的,因为如果目录剂量不是包含任何匹配的文件*.png
(如在assets
、a
和a2
目录中),那么该模式将在$n
.
或者,更短,
find assets -type f -name '*.png' \
-exec sh -c 'for n; do mv "$n" "${n%.png}_old.png"; done' sh {} +
测试:
$ mkdir -p assets/a{,2}/b{,2,3}
$ touch assets/a{,2}/b{,2,3}/{a,b,c,d}.png
$ tree
.
`-- assets
|-- a
| |-- b
| | |-- a.png
| | |-- b.png
| | |-- c.png
| | `-- d.png
| |-- b2
| | |-- a.png
| | |-- b.png
| | |-- c.png
| | `-- d.png
| `-- b3
| |-- a.png
| |-- b.png
| |-- c.png
| `-- d.png
`-- a2
|-- b
| |-- a.png
| |-- b.png
| |-- c.png
| `-- d.png
|-- b2
| |-- a.png
| |-- b.png
| |-- c.png
| `-- d.png
`-- b3
|-- a.png
|-- b.png
|-- c.png
`-- d.png
9 directories, 24 files
(find
这里执行的命令)
$ tree
.
`-- assets
|-- a
| |-- b
| | |-- a_old.png
| | |-- b_old.png
| | |-- c_old.png
| | `-- d_old.png
| |-- b2
| | |-- a_old.png
| | |-- b_old.png
| | |-- c_old.png
| | `-- d_old.png
| `-- b3
| |-- a_old.png
| |-- b_old.png
| |-- c_old.png
| `-- d_old.png
`-- a2
|-- b
| |-- a_old.png
| |-- b_old.png
| |-- c_old.png
| `-- d_old.png
|-- b2
| |-- a_old.png
| |-- b_old.png
| |-- c_old.png
| `-- d_old.png
`-- b3
|-- a_old.png
|-- b_old.png
|-- c_old.png
`-- d_old.png
9 directories, 24 files
答案2
使用与 find 一起命名:
find . -type f -name '*.png' -exec prename 's/\.png$/_old.png/' {} +
答案3
没有find
给定固定的目录结构,您可以对目录使用通配符:
rename -n s/.png/_old.png/ */*/*.png
(更改-n
为-v
实际运行命令)。
如果 PNG 位于不同的目录级别,您仍然可以避免find
:
shopt -s globstar
rename -n s/.png/_old.png/ **/*.png
(使用globstar
set,**
匹配任意数量的目录级别)
在 Debian 及其衍生版本上,prename
称为rename
,但它是相同的命令。