从find命令

时间:2015-06-16 22:03:21

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

find $DIR -name "*.mod" -type f -exec remodup {} \;

我也试过| xargs语法。 findxargs都告诉“`remodup`不存在。

我可以将函数移动到一个单独的bash脚本中并调用脚本,但我不想将该函数复制到路径目录中(但是),所以我需要调用函数脚本绝对路径或总是从同一位置调用调用脚本。

(我可能会将fdupes用于此特定任务,但我想找到一种方法

  1. find命令调用函数;
  2. 从另一个脚本的相对路径调用一个脚本;或
  3. 对使用${F/.mod/}命令找到的文件使用find语法(或其他bash变量操作)。)

4 个答案:

答案 0 :(得分:5)

您需要先使用以下方法导出该功能:

export -f remodup

然后将其用作:

find $DIR -name "*.mod" -type f -exec bash -c 'remodup "$1"' - {} \;

答案 1 :(得分:5)

您可以手动循环find的结果。

find "$dir" -name "*.mod" -type f -print0 | while IFS= read -rd $'\0' file; do
    remodup "$file"
done

-print0-d $'\0'使用NUL作为分隔符,允许在文件名中添加换行符。 IFS=确保空格,因为文件名的开头不会被剥离。 -r禁用反斜杠转义。所有这些选项的总和是在文件名中允许尽可能多的特殊字符而不进行修改。

答案 2 :(得分:2)

投入第三个选项:

find "$dir" -name "*.mod" -type f \
  -exec bash -s -c "$(declare -f remodup)"$'\n'' for arg; do remodup "$arg"; done' _ {} +

这通过argv传递函数,而不是通过环境,并且(通过使用{} +而不是{} ;)使用尽可能少的shell实例。

我会用John Kugelman的答案作为我的第一选择,这是我的第二选择。

答案 3 :(得分:2)

鉴于您没有使用find的许多功能,您可以使用纯bash解决方案来迭代所需的文件。

shopt -s globstar nullglob
for fname in ./"$DIR"/**/*.mod; do
    [[ -f $fname ]] || continue
    f=${fname##*/}
    remodup "$f"
done