Shell Bash 子字符串替换 ${foo/a/b} 的通用等价物
Shell generic equivalent of Bash Substring replacement ${foo/a/b}
是否有shell独立等价的Bash子串替换:
foo=Hello
echo ${foo/o/a} # will output "Hella"
大多数时候我可以使用 bash
所以这不是问题,但是当与 find -exec
结合使用时它不起作用。例如,要将所有 .cpp
文件重命名为 .c
,我想使用:
# does not work
find . -name '*.cpp' -exec mv {} {/.cpp$/.c}
目前,我正在使用:
# does work, but longer
while read file; do
mv "$file" "${file/.cpp$/.c}";
done <<< $(find . -name '*.cpp')
理想情况下,可以在脚本中使用的解决方案更好!
使用 find
和 -exec
你可以这样做:
find . -name '*.cpp' -exec bash -c 'f=""; mv "$f" "${f/.cpp/.c}"' - '{}' \;
然而,这将为每个文件名创建 bash -c
,因此出于性能原因,使用 xargs
或这样的 for
循环更好:
while IFS= read -d '' -r file; do
mv "$file" "${file/.cpp/.c}"
done < <(find . -name '*.cpp' -print0)
顺便说一句,使用 bash
的替代方法是使用 rename
。如果你有 cool 版本的 rename
命令,它与 perl
一起提供,你可以这样做:
find -name '*.cpp' -exec rename 's/\.cpp$/.c/' {} +
上面的例子假设你有 GNU findutils
,有了这个你不需要传递当前目录,因为它是默认的。如果你没有GNUfindutils
,你需要显式传递:
find . -name '*.cpp' -exec rename 's/\.cpp$/.c/' {} +
是否有shell独立等价的Bash子串替换:
foo=Hello
echo ${foo/o/a} # will output "Hella"
大多数时候我可以使用 bash
所以这不是问题,但是当与 find -exec
结合使用时它不起作用。例如,要将所有 .cpp
文件重命名为 .c
,我想使用:
# does not work
find . -name '*.cpp' -exec mv {} {/.cpp$/.c}
目前,我正在使用:
# does work, but longer
while read file; do
mv "$file" "${file/.cpp$/.c}";
done <<< $(find . -name '*.cpp')
理想情况下,可以在脚本中使用的解决方案更好!
使用 find
和 -exec
你可以这样做:
find . -name '*.cpp' -exec bash -c 'f=""; mv "$f" "${f/.cpp/.c}"' - '{}' \;
然而,这将为每个文件名创建 bash -c
,因此出于性能原因,使用 xargs
或这样的 for
循环更好:
while IFS= read -d '' -r file; do
mv "$file" "${file/.cpp/.c}"
done < <(find . -name '*.cpp' -print0)
顺便说一句,使用 bash
的替代方法是使用 rename
。如果你有 cool 版本的 rename
命令,它与 perl
一起提供,你可以这样做:
find -name '*.cpp' -exec rename 's/\.cpp$/.c/' {} +
上面的例子假设你有 GNU findutils
,有了这个你不需要传递当前目录,因为它是默认的。如果你没有GNUfindutils
,你需要显式传递:
find . -name '*.cpp' -exec rename 's/\.cpp$/.c/' {} +