从find命令执行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

我在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命令调用此函数:

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的版本不同,则不能保证它会真正支持您导出的函数。