对使用 find 命令找到的每个文件运行 Bash 函数

对使用 find 命令找到的每个文件运行 Bash 函数

我目前有这个命令,它成功地在自己的行上打印每个文件名:

find . -exec echo {} \;

我试图分割逻辑,以便find命令执行一个函数。基于这个问题我试过这个:

my_function() {
    echo $1
}
export -f my_function
find . -exec bash -c 'my_function "$@"' bash {} +

然后我得到这个输出:

.

我也尝试替换$@$*,但这会导致$1每个文件都没有换行符。我想运行检查每个文件的逻辑,所以我想$1一次只检查一个文件。我尝试使用空格分割输出,for file in $1但这对于文件名中包含空格的文件不起作用。如何为命令找到的每个文件运行 Bash 函数find

编辑:这是我正在使用的整个脚本。看起来效果很好。

# Ensures that non-csproj text files are formatted with LF line endings.
format() {
    for pathname do
        if [[ $pathname == *"git"* ]]; then
            continue
        elif [[ $pathname == *"csproj"* ]]; then
            continue
        fi
        dos2unix $pathname
    done
}
export -f format
find . -exec bash -c 'format "$@"' bash {} \;

答案1

要在当前目录中及其下的每个常规文件上运行dos2unix --newline,请避免名称包含字符串的任何文件git

find . -type f ! -name '*git*' -exec dos2unix --newline {} +

也就是说,找到名称与模式不匹配的所有常规文件*git*,并dos2unix --newline一次尽可能大批量地运行所有这些文件。更改! -name '*git*'! -path '*git*'以避免路径名包含该字符串的任何文件git(例如目录中的文件.git)。

要明确避免任何目录,但要包含其名称中.git可能包含的任何其他内容:git

find . -name .git -prune -o -type f -exec dos2unix --newline {} +

即使输入使用从搜索树中删除此类路径调用find的任何目录,也会停止形式。.git-prune


在编辑问题之前回答:

您的函数仅打印出其第一个参数。点是您与 一起使用的顶级搜索路径find。它会通过,因为您没有对目录条目进行任何特定的过滤(例如,-type f仅针对常规文件,或-name,或任何其他类型的find测试)。

如果您希望函数打印其每个参数,请使用

my_function() {
    printf '%s\n' "$@"
}

让我们printf打印每个参数并在中间换行,或者

my_function() {
    for pathname do
        printf '%s\n' "$pathname"
    done
}

它循环遍历参数并printf为每个参数调用一次。

如果您调用如下函数,则预计可以正常工作

my_function "$@"

从您的内联bash -c脚本中。扩展"$@"为给予脚本的所有参数,单独引用。

另一种方法是将循环移至bash -c脚本中:

for pathname do
    my_function "$pathname"
done

然后有

my_function () {
    printf '%s\n' "$1"
}

这将明确地执行您所说的操作,即为每个路径名调用该函数一次。

find命令看起来像

find . -exec bash -c 'for pathname do my_function "$pathname"; done' bash {} +

或者,可以说更具可读性,

find . -exec bash -c '
    for pathname do
        my_function "$pathname"
    done' bash {} +

顺便说一句,这与

shopt -s globstar nullglob dotglob

for pathname in ./**/*; do
    my_function "$pathname"
done

.不会被处理。使用它,您不必导出您的my_function函数。

通过函数内部的循环(如本答案中的前两段代码),这将被缩短为

shopt -s globstar nullglob dotglob

my_function ./**/*

相关内容