我目前有这个命令,它成功地在自己的行上打印每个文件名:
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 ./**/*