使用 find 的输出循环处理文件
Process files in loop with output from find
常见问题常年变异
不考虑 find 的 -exec 函数和 xargs,如何在循环中处理使用 find 的函数的输出?
目的是依靠一个函数来包含一个经常重复的带有许多参数的查找语句。也忽略 possibility of storing the args in an array,我怎样才能简单地遍历经常重复的 find 语句的结果,把它放在一个函数中?
一个简单的例子:
function ftf ()
{
find . -type f -name "*" 2> /dev/null
}
函数在 /etc/cups 目录中 运行 时找到这些文件。
._. ftf
./raw.types
./subscriptions.conf.O
./cupsd.conf
./subscriptions.conf
./raw.convs
./printers.conf
./cups-files.conf
./printers.conf.O
./snmp.conf
./cups-browsed.conf
但是 运行宁 basename
结果,使得循环似乎只在最后一个文件上运行。
._. for fp in "$(ftf "")"; do printf "%s\n" "$(basename "$fp")"; done
cups-browsed.conf
仅打印文件似乎可行:
for fp in "$(ftf "")"; do printf "%s\n" "$fp"; done
./raw.types
./subscriptions.conf.O
./cupsd.conf
./subscriptions.conf
./raw.convs
./printers.conf
./cups-files.conf
./printers.conf.O
./snmp.conf
./cups-browsed.conf
但实际上它只是一次性打印出find的全部输出:
._. for fp in "$(ftf "")"; do echo "new line!"; printf "%s\n" "$fp"; done
new line!
./raw.types
./subscriptions.conf.O
./cupsd.conf
./subscriptions.conf
./raw.convs
./printers.conf
./cups-files.conf
./printers.conf.O
./snmp.conf
./cups-browsed.conf
尽管有其他方法可以做到这一点,但我如何才能简单地遍历结果?
https://mywiki.wooledge.org/BashFAQ/001 and https://mywiki.wooledge.org/DontReadLinesWithFor 解决了您要执行的操作。
假设您的文件名不包含换行符:
while IFS= read -r fp; do
printf '%s\n' "$fp"
done < <(ftf)
顺便说一下,你的函数应该是:
ftf() {
find . -type f 2>/dev/null
}
因为你不需要 function
和 ()
并且后者更便携,并且说 -name "*"
意味着“任何名称”所以你不需要指定那,我假设您正在尝试重定向 stderr 但错过了 >
.
如果您的文件名可以包含换行符,那么:
ftf() {
find . -type f -print0 2>/dev/null
}
while IFS= read -r -d '' fp; do
printf '%s[=12=]' "$fp"
done < <(ftf)
常见问题常年变异
不考虑 find 的 -exec 函数和 xargs,如何在循环中处理使用 find 的函数的输出?
目的是依靠一个函数来包含一个经常重复的带有许多参数的查找语句。也忽略 possibility of storing the args in an array,我怎样才能简单地遍历经常重复的 find 语句的结果,把它放在一个函数中?
一个简单的例子:
function ftf ()
{
find . -type f -name "*" 2> /dev/null
}
函数在 /etc/cups 目录中 运行 时找到这些文件。
._. ftf
./raw.types
./subscriptions.conf.O
./cupsd.conf
./subscriptions.conf
./raw.convs
./printers.conf
./cups-files.conf
./printers.conf.O
./snmp.conf
./cups-browsed.conf
但是 运行宁 basename
结果,使得循环似乎只在最后一个文件上运行。
._. for fp in "$(ftf "")"; do printf "%s\n" "$(basename "$fp")"; done
cups-browsed.conf
仅打印文件似乎可行:
for fp in "$(ftf "")"; do printf "%s\n" "$fp"; done
./raw.types
./subscriptions.conf.O
./cupsd.conf
./subscriptions.conf
./raw.convs
./printers.conf
./cups-files.conf
./printers.conf.O
./snmp.conf
./cups-browsed.conf
但实际上它只是一次性打印出find的全部输出:
._. for fp in "$(ftf "")"; do echo "new line!"; printf "%s\n" "$fp"; done
new line!
./raw.types
./subscriptions.conf.O
./cupsd.conf
./subscriptions.conf
./raw.convs
./printers.conf
./cups-files.conf
./printers.conf.O
./snmp.conf
./cups-browsed.conf
尽管有其他方法可以做到这一点,但我如何才能简单地遍历结果?
https://mywiki.wooledge.org/BashFAQ/001 and https://mywiki.wooledge.org/DontReadLinesWithFor 解决了您要执行的操作。
假设您的文件名不包含换行符:
while IFS= read -r fp; do
printf '%s\n' "$fp"
done < <(ftf)
顺便说一下,你的函数应该是:
ftf() {
find . -type f 2>/dev/null
}
因为你不需要 function
和 ()
并且后者更便携,并且说 -name "*"
意味着“任何名称”所以你不需要指定那,我假设您正在尝试重定向 stderr 但错过了 >
.
如果您的文件名可以包含换行符,那么:
ftf() {
find . -type f -print0 2>/dev/null
}
while IFS= read -r -d '' fp; do
printf '%s[=12=]' "$fp"
done < <(ftf)