현재 디렉터리와 존재하지 않는 모든 하위 디렉터리에서 모든 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 $@;
}
이는 다음과 같이 한 줄로 정리할 수 있습니다.
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
순수한 배쉬:
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
스타일에 더 쉽게 사용할 수 있는 다른 이름을 사용하세요.