我认为我不太清楚Unix中的find命令是如何工作的;我有这个代码来计算每个文件夹中的文件数,但我想计算找到的每个文件的行数,并将总数保存在变量中。
find "$d_path" -type d -maxdepth 1 -name R -print0 | while IFS= read -r -d '' file; do
nb_fichier_R="$(find "$file" -type f -maxdepth 1 -iname '*.R' | wc -l)"
nb_ligne_fichier_R= "$(find "$file" -type f -maxdepth 1 -iname '*.R' -exec wc -l {} +)"
echo "$nb_ligne_fichier_R"
done
输出:
43 .//system d exploi/r-repos/gbm/R/basehaz.gbm.R
90 .//system d exploi/r-repos/gbm/R/calibrate.plot.R
45 .//system d exploi/r-repos/gbm/R/checks.R
178 total: File name too long
我可以保存到变量中的总行数吗?这里在我的例子中只保存178和我文件夹中的每个文件" $ d_path"
非常感谢
答案 0 :(得分:0)
解决方案:
find "$d_path" -type d -maxdepth 1 -name R | while IFS= read -r file; do
nb_fichier_R="$(find "$file" -type f -maxdepth 1 -iname '*.R' | wc -l)"
echo "$nb_fichier_R" #here is fine
find "$file" -type f -maxdepth 1 -iname '*.R' | while IFS= read -r fille; do
wc -l $fille #here is the problem nothing shown
done
done
说明:
添加-print0
第一个查找没有产生新行,因此您必须告诉read -d ''
告诉它不要查找换行符。您的后续查找输出换行符,以便您可以使用不带分隔符的读取。我从所有来电中删除了-print0
和-d ''
,因此它是一致且惯用的。 unix世界的新行很好。
答案 1 :(得分:0)
对于命令:
find "$d_path" -type d -maxdepth 1 -name R -print0
最多可以有一个匹配的目录("$d_path/R"
)。对于那个目录,您要打印:
*.R
我发现,使用辅助shell脚本最容易处理$d_path
和文件名中的空格。辅助脚本处理在其命令行上命名的目录。然后,您可以从主find
命令调用该脚本。
shopt -s nullglob;
for dir in "$@"
do
count=0
for file in "$dir"/*.R; do ((count++)); done
echo "$count"
wc -l "$dir"/*.R </dev/null
done
shopt -s nullglob
选项意味着如果没有.R
个文件(名称不以.
开头),则glob扩展为空,而不是扩展为最后包含*.R
的字符串。这个脚本很方便。 wc
上的I / O重定向确保如果没有文件,它会从/dev/null
读取,报告0行(而不是等待您输入内容)。
另一方面,find
命令将查找以.
开头的名称以及不以 for file in "$dir"/*.R "$dir"/.*.R; do ((count++)); done
开头的名称,而通用符号则不会。最简单的方法是使用两个整体:
find
或使用 find . -type f -name '*.R' -exec sh -c 'echo $#' arg0 {} +
(相当谨慎):
find "$d_path" -type d -maxdepth 1 -name R -exec sh ./counter.sh {} +
-maxdepth 1
此脚本允许多个子目录(如果删除counter.sh
)的可能性,并调用sh ./counter.sh
并将所有要检查的目录作为参数。脚本本身会仔细处理文件名,以便名称中是否有空格,制表符或换行符(或任何其他字符),它将正常工作。 find
命令的counter.sh
部分假定$PATH
脚本位于当前目录中。如果可以在sh
上找到,则可以删除./
和find
。
使用-print0
执行带有文件名参数列表的命令的技术非常强大。它避免了xargs -0
和使用$IFS
的问题,但为您提供了对任意文件名的可靠处理,包括带有空格,制表符和换行符的名称。如果还没有一个命令可以执行您需要的操作(但您可以将其编写为shell脚本),那么请执行此操作并使用它。如果您可能需要多次执行此任务,则可以保留脚本。如果您确定不会,则可以在完成后将其删除。处理具有尴尬名称的文件通常比处理{{1}}更容易。
答案 2 :(得分:0)
考虑这个解决方案:
# If `"$dir"/*.R` doesn't match anything, yield nothing instead of giving the pattern.
shopt -s nullglob
# Allows matching both `*.r` and `*.R` in one expression. Using them separately would
# give double results.
shopt -s nocaseglob
while IFS= read -ru 4 -d '' dir; do
files=("$dir"/*.R)
echo "${#files[@]}"
for file in "${files[@]}"; do
wc -l "$file"
done
# Use process substitution to prevent going to a subshell. This may not be
# necessary for now but it could be useful to future modifications.
# Let's also use a custom fd to keep troubles isolated.
# It works with `-u 4`.
done 4< <(exec find "$d_path" -type d -maxdepth 1 -name R -print0)
另一种形式是使用readarray
一次分配所有找到的目录。唯一需要注意的是它只能读取正常的换行终止路径。
shopt -s nullglob
shopt -s nocaseglob
readarray -t dirs < <(exec find "$d_path" -type d -maxdepth 1 -name R)
for dir in "${dirs[@]}"; do
files=("$dir"/*.R)
echo "${#files[@]}"
for file in "${files[@]}"; do
wc -l "$file"
done
done
答案 3 :(得分:0)
也许我错过了一些东西,但这不是你想要的吗?
wc -l R/*.[Rr]