如何找到当前目录和所有子目录中的所有xml文件,这些文件不存在从...开始 <
在第一行。
我已经尝试过这个,但grep
不起作用:
find . -type f -name '*.xml' | grep "^[^<]" | head -n 1
答案1
您已经有了一些可靠的答案,但是我将提供另一种选择 - XML 规范非常严格,并且文件不start with<
实际上根本不是XML。
因此,一个简单的方法可能是简单地测试文件是否“有效”。所有 XML 解析器都可以执行此操作,但这里有一个示例:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
foreach my $filename ( @ARGV ) {
eval { XML::Twig -> new -> parsefile ( $filename ); };
print "File: $filename is not valid XML $@\n" if $@;
}
这可以 oneliner 化为:
perl -MXML::Twig -e 'foreach ( @ARGV ) { eval { XML::Twig -> new -> parsefile ( $_ ) }; print "File: $filename is not valid XML $@\n" if $@;' *.xml
如果递归遍历很重要,那么File::Find
也会有帮助:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
use File::Find;
sub check_valid_xml {
#skip any files that don't end in '.xml'
next unless m/\.xml$/;
#validate this file
eval { XML::Twig->new->parsefile($File::Find::name); };
#report errors if detected - parser will abort on invalid XML
if ($@) { print "File $File::Find::name is not valid XML $@"; }
}
find( \&check_valid_xml, "." );
这将检测到任何“坏 XML”,其中将包含您在问题中指定的文件。
答案2
要 grep 每个文件的第一行并打印它们是否匹配,可以使用 xargs 和 awk
find . -type f -name "*.xml" -print0 | xargs -0 -I{} awk 'NR==1&&!/^</' {}
打印文件的文件名
find . -type f -name "*.xml" -print0 | xargs -0 -I{} awk 'NR==1&&!/^</{print FILENAME}' {}
答案3
如果您awk
支持 nextfile 语句(大多数都支持):
find . -name '*.xml' -type f \( -size 0 -print -o -exec awk '
!/^</ {print FILENAME}; {nextfile}' {} + \)
答案4
纯bash:
shopt -s globstar
for i in **/*.c;do
read -N 1 h < "$i";
if [[ $h != "<" ]]; then
# echo "found $i";
# do stuff with "$i"
fi;
done
read -N 1
从文件中读取单个字符,而无需分叉/执行任何内容。如果您只需要文件名列表,请使用其他更容易使用该-print0
样式的名称。