假设我有以下文件:
foo.coffee
foo.js
bar.js
有没有简单的方法可以知道rm *.js
是否存在相应的.coffee
文件?在示例中,这样的命令将删除foo.js
以下内容:
foo.coffee
bar.js
我正在寻找某种rm
包装,因为我需要做一个递归rm -r
。
答案1
一点儿狂欢(使用所有最佳实践!):
shopt -s nullglob
for f in *.js; do
coffee=${f%.js}.coffee
[[ -f $coffee ]] && rm -v -- "$f"
done
nullglob
是shell 可选行为因此,*.js
如果没有扩展名的文件,它将扩展为空字符串js
。- 使用shell 参数扩展删除扩展名
.js
并用.coffee
变量中的替换它coffee
。 rm
与开关(详细)一起使用-v
,以便您看到正在发生的事情。rm
也用于--
标记选项的结束,以防万一有一个以连字符开头的文件:在这种情况下,rm
会产生混淆并尝试解释一个选项。- 该
[[ ... ]]
构造是一个条件构造,并使用条件表达式。请注意,我使用的是强大的双方括号[[
而不是单一的[
。非常好的做法(在狂欢)。 - 请注意,引用是完美的。对于名称中包含空格或奇怪符号的文件,它是 100% 安全的。
为了测试目的,您应将其放在echo
前面rm
:
[[ -f $coffee ]] && echo rm -v -- "$f"
这样它只会回显命令而不会删除任何内容。当您对此感到满意时,删除echo
。
享受!
答案2
创建此脚本(我将其命名为remove.sh):
#!/bin/bash
if [ -z "$3" ]; then
echo "Usage: $0 <directory> <extension-to-remove> <conditional-extension>"
exit 1
fi
if [ ! -d "$1" ]; then
echo "Invalid directory."
exit 1
fi
for FILE in $(find $1 -name "*.$3"); do
rm -v ${FILE%.$3}.$2
done
然后运行remove.sh <directory> js coffee
。