Linux 显示所有1行php文件的Shell脚本
尝试创建一个shell脚本,以递归方式搜索目录并显示仅包含一行的所有php文件的列表 我认为我的IF语句有问题,但我不确定Linux 显示所有1行php文件的Shell脚本,linux,bash,sh,Linux,Bash,Sh,尝试创建一个shell脚本,以递归方式搜索目录并显示仅包含一行的所有php文件的列表 我认为我的IF语句有问题,但我不确定 #!/bin/bash shopt -s nullglob for f in *.php do if [ 'find . -type f | wc -l $f == 1' ]; then echo "$f" fi awk救援 for f in *.php; do awk 'END{ if(NR==1) print FILENAME}' $f; done 对于需要使用f
#!/bin/bash
shopt -s nullglob
for f in *.php
do
if [ 'find . -type f | wc -l $f == 1' ];
then echo "$f"
fi
awk
救援
for f in *.php; do awk 'END{ if(NR==1) print FILENAME}' $f; done
对于需要使用find的递归查找,可以选择一种方法
find -name *.php -print | xargs -L1 awk 'NR>1{exit} END{if(NR==1) print FILENAME}'
awk
救援
for f in *.php; do awk 'END{ if(NR==1) print FILENAME}' $f; done
对于需要使用find的递归查找,可以选择一种方法
find -name *.php -print | xargs -L1 awk 'NR>1{exit} END{if(NR==1) print FILENAME}'
这将递归搜索一行PHP文件:
find -name '*.php' -exec bash -c '[[ "$(wc -l < "$0")" -eq 1 ]] && echo "$0"' '{}' ';'
然而,我上面写的仍然没有多大意义,也不是我认为你想要的
[
本身是一个用于将算术和字符串比较转换为if
友好形式的命令。您可以将其与输出替换(使用$(…)
语法)相结合,以测试命令的输出是否等于1
if [ "$(wc -l < "$f")" -eq 1 ]; then
echo "$f"
fi
如果[“$(wc-l<“$f”)”-等式1];则
回音“$f”
fi
这将递归搜索一行PHP文件:
find -name '*.php' -exec bash -c '[[ "$(wc -l < "$0")" -eq 1 ]] && echo "$0"' '{}' ';'
然而,我上面写的仍然没有多大意义,也不是我认为你想要的
[
本身是一个用于将算术和字符串比较转换为if
友好形式的命令。您可以将其与输出替换(使用$(…)
语法)相结合,以测试命令的输出是否等于1
if [ "$(wc -l < "$f")" -eq 1 ]; then
echo "$f"
fi
如果[“$(wc-l<“$f”)”-等式1];则
回音“$f”
fi
虽然有点笨重,但我们应该做到这一点
更优雅的是
find . -type f -name '*.php' -exec wc -l {} \; | egrep "^\s*1\s"
虽然有点笨重,但我们应该做到这一点
更优雅的是
find . -type f -name '*.php' -exec wc -l {} \; | egrep "^\s*1\s"
这将找到“一行程序”:
当除一行之外的所有行都为空时,该行将找到碰巧有多行的“一行”:
find . -type f -name '*.php' -exec grep -Hcm2 '[^[:space:]]' {} + |
sed -n '/:1$/{s///;p}'
grep选项-Hcm2
的意思是“始终打印文件名,只打印匹配的计数,最多匹配两行。”模式$
匹配任何行,而模式“[^[:space:][]”
匹配包含非空白字符的任何行。以{}结束-exec
+
告诉find
提供一个文件列表,而不是触发每个文件上的exec
,这样效率更高。最后,sed
打印以:1
结尾的行(删除:1
),它将是包含非空白字符的行数正好为1的文件的文件名
这可能比wc
更有效,因为它通常会在第二行停止读取,而不是仅仅为了检查文件是否有多行而读取整个文件
(另外,关于wc
:如果文件恰好有一行,但该行没有以换行符结尾,则wc
将报告它有0行。因此,如果您将wc输出筛选为等于1,则可能会丢失一些文件。)
如果您最近有一次bash,您可以通过启用**
globs来避免find
:
shopt -s globstar nullglob
grep -Hcm2 "[^[:space:]]" **/*.php | sed -n '/:1$/{s///;p}'
如果文件路径中有换行符的文件,上述任何一种破解方法都不起作用。但是你没有,对吗?:-)这将找到“一行”:
当除一行之外的所有行都为空时,该行将找到碰巧有多行的“一行”:
find . -type f -name '*.php' -exec grep -Hcm2 '[^[:space:]]' {} + |
sed -n '/:1$/{s///;p}'
grep选项-Hcm2
的意思是“始终打印文件名,只打印匹配的计数,最多匹配两行。”模式$
匹配任何行,而模式“[^[:space:][]”
匹配包含非空白字符的任何行。以{}结束-exec
+
告诉find
提供一个文件列表,而不是触发每个文件上的exec
,这样效率更高。最后,sed
打印以:1
结尾的行(删除:1
),它将是包含非空白字符的行数正好为1的文件的文件名
这可能比wc
更有效,因为它通常会在第二行停止读取,而不是仅仅为了检查文件是否有多行而读取整个文件
(另外,关于wc
:如果文件恰好有一行,但该行没有以换行符结尾,则wc
将报告它有0行。因此,如果您将wc输出筛选为等于1,则可能会丢失一些文件。)
如果您最近有一次bash,您可以通过启用**
globs来避免find
:
shopt -s globstar nullglob
grep -Hcm2 "[^[:space:]]" **/*.php | sed -n '/:1$/{s///;p}'
如果您的文件路径中有换行符的文件,则上述黑客攻击都不起作用。但是您没有,对吗?:-)Bash 4提供了“globstar”shell选项来处理递归要求:
shopt -s globstar
wc -l **/*.php | awk '$1==1' | sed 's/^ *[0-9]* *//'
或者,如果您不喜欢sed,您可以在管道的awk部分添加更多内容:
wc -l **/*.php | awk '$1==1{sub(/^ *[0-9]+ */,"");print}'
这两种解决方案,以及(目前)发布的所有其他解决方案,都会受到影响,因为长文件将被完整读取。您真的不需要这样做——如果您看到第二行,您可以跳过任何文件。因此,再次依赖Bash 4的“globstar”进行递归:
awk 'FNR==1{a[FILENAME]} FNR==2{delete a[FILENAME];nextfile} END{for(f in a){print f}}' **/*.php
为了便于解释,这是:
awk '
# Upon reading the first line of a file, add its name to an array.
FNR==1 {a[FILENAME]}
# Upon reading the second line, delete it from the array and move on.
FNR==2 {delete a[FILENAME];nextfile}
# Once we've processed all files, print what's left in the array.
END {for(f in a){print f}}
' **/*.php
每个文件最多读取两行。可能比wc-l
或grep-c快得多。Bash 4提供了“globstar”shell选项来处理递归要求:
shopt -s globstar
wc -l **/*.php | awk '$1==1' | sed 's/^ *[0-9]* *//'
或者,如果您不喜欢sed,您可以在管道的awk部分添加更多内容:
wc -l **/*.php | awk '$1==1{sub(/^ *[0-9]+ */,"");print}'
这两种解决方案,以及(目前)发布的所有其他解决方案,都会受到影响,因为长文件将被完整读取。您真的不需要这样做——如果您看到第二行,您可以跳过任何文件。因此,再次依赖Bash 4的“globstar”进行递归:
awk 'FNR==1{a[FILENAME]} FNR==2{delete a[FILENAME];nextfile} END{for(f in a){print f}}' **/*.php
扩展以便于解释