如何grep所有不以“

如何grep所有不以“

如何找到当前目录和所有子目录中的所有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样式的名称。

相关内容