从find命令执行bash函数
我在bash中定义了一个函数,它检查两个文件是否存在,比较它们是否相等,并删除其中一个文件从find命令执行bash函数,bash,xargs,Bash,Xargs,我在bash中定义了一个函数,它检查两个文件是否存在,比较它们是否相等,并删除其中一个文件 function remodup { F=$1 G=${F/.mod/} if [ -f "$F" ] && [ -f "$G" ] then cmp --silent "$F" "$G" && rm "$F" || echo "$G was modified" fi } 然后我想通过find命令调用此函数: fin
function remodup {
F=$1
G=${F/.mod/}
if [ -f "$F" ] && [ -f "$G" ]
then
cmp --silent "$F" "$G" && rm "$F" || echo "$G was modified"
fi
}
然后我想通过find命令调用此函数:
find $DIR -name "*.mod" -type f -exec remodup {} \;
我还尝试了| xargs
语法。find
和xargs
都告诉我们“remodup”不存在
我可以将函数移动到一个单独的bash脚本中并调用该脚本,但我不想将该函数复制到路径目录中,因此我需要使用绝对路径调用函数脚本,或者从同一位置调用调用脚本
(我可能可以使用fdupes
执行此特定任务,但我想找到一种方法
find
命令调用函数find
命令找到的文件使用${F/.mod/}
语法(或其他bash变量操作)您需要首先使用以下方法导出函数:
export -f remodup
然后将其用作:
find $DIR -name "*.mod" -type f -exec bash -c 'remodup "$1"' - {} \;
您可以手动循环
查找的结果
while IFS= read -rd $'\0' file; do
remodup "$file"
done < <(find "$dir" -name "*.mod" -type f -print0)
而IFS=read-rd$'\0'文件;做
remodup“$file”
完成<添加第三个选项:
find "$dir" -name "*.mod" -type f \
-exec bash -s -c "$(declare -f remodup)"$'\n'' for arg; do remodup "$arg"; done' _ {} +
这将通过argv传递函数,而不是通过环境,并且(通过使用{}+
而不是{};
)使用尽可能少的shell实例
我将使用John Kugelman的答案作为第一选择,这是第二选择。鉴于您没有使用find
的许多功能,您可以使用纯bash
解决方案来迭代所需的文件
shopt -s globstar nullglob
for fname in ./"$DIR"/**/*.mod; do
[[ -f $fname ]] || continue
f=${fname##*/}
remodup "$f"
done
我会把它写成-d'
;编写-d$'\0'
意味着shell实际上可以在字符串中表示NUL(除了作为终止符),它不表示NUL,也不能表示NUL。也就是说,我倾向于更喜欢这个选项,它比按照找到的每个文件启动bash
实例更有效,就像当前提出的另一个答案一样,我发现for循环更容易阅读。例如:,对于“find”base“-name”关键字“`”中的结果;不要重复结果;完成
该方法不安全。它将在文件名中包含空格时失败。正如答案详细解释的那样,我在上面所做的一切都有其原因。while;做;JohnKugelman已完成declare-f
而不是export-f
?,因为由于shellshock补丁,导出的函数在所有版本的bash之间不兼容。如果您调用的shell与您所在的shell的版本不同,则不能保证它会真正支持您导出的函数。