grep início do arquivo?

10

Em um shell linux, quero ter certeza de que um determinado conjunto de arquivos comece com <? , tendo a string exata e nenhum outro caractere no começo. Como posso grep ou usar algum outro para expressar "arquivo começa com"?

Edit: estou curingeando isso, e head não dá um nome de arquivo na mesma linha, então quando eu o grep, eu não vejo o nome do arquivo. Além disso, "^<?" não parece dar os resultados corretos; basicamente eu estou entendendo isso:

$> head -1 * | grep "^<?"
<?
<?
<?
<?
<?
...

Todos os arquivos são realmente bons.

    
por user13743 12.03.2010 / 20:16

9 respostas

11

No Bash:

for file in *; do [[ "$(head -1 "$file")" =~ ^\<\? ]] || echo "$file"; done

Verifique se eles são arquivos:

for file in *; do [ -f "$file" ] || continue; [[ "$(head -1 "$file")" =~ ^\<\? ]] || echo "$file"; done

    
por 12.03.2010 / 23:31
3

Você pode usar o awk para isso:

$ cat test1
<?xxx>
111
222
333
$ cat test2
qqq
aaa
zzz
$ awk '/^<\?/{print "Starting with \"<?\":\t" ARGV[ARGIND]; nextfile} {print "Not starting with \"<?\":\t" ARGV[ARGIND]; nextfile}' *
Starting with "<?":     test1
Not starting with "<?": test2
$
    
por 12.03.2010 / 22:13
3

Exceto para arquivos vazios, esse script Perl parece funcionar:

perl -e 'while (<>) { print "$ARGV\n" unless m/^<\?/; close ARGV; }' *

Não sei imediatamente como lidar com arquivos vazios; Eu ficaria tentado a tratá-los como um caso especial separado:

find . -type f -size +0 -print0 |
    xargs -0 perl -e 'while (<>) { print "$ARGV\n" unless m/^<\?/; close ARGV; }'
    
por 12.03.2010 / 23:59
3

Faça o grep :

$ head -n 1 * | grep -B1 "^<?"
==> foo <==
<?
--
==> bar <==
<?
--
==> baz <==
<?

Analise os nomes dos arquivos:

$ head -n 1 * | grep -B1 "^<?" | sed -n 's/^==> \(.*\) <==$//p'
foo
bar
baz
    
por 15.03.2010 / 00:02
2

Tente isso

for i in 'find * | grep "php$"'; do echo -n $i " -> "; head -1 $i; done

Isto irá obter uma lista de todos os arquivos que terminam em PHP e, em seguida, passará por ele. ecoando o nome do arquivo e, em seguida, imprimindo a primeira linha do arquivo. Acabei de inserir

lhe dará saída como:

calendar.php  -> <?php
error.php  -> <?php
events.php  -> <?php
gallery.php  ->
index.php  -> <?php
splash.php  -> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
information.php  -> <?php
location.php  -> <?php
menu.php  -> <?php
res.php  -> <?php
blah.php  -> <?php

então você pode colocar um grep normal no final para se livrar do que quer ver e encontrar apenas exceções

for i in 'find * | grep "php$"'; do echo -n $i " -> "; head -1 $i; done | grep -v "<?php"

saída:

gallery.php  ->
splash.php  -> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    
por 12.03.2010 / 21:01
1

Bash 4.0

#!/bin/bash
shopt -s globstar
for php file in /path/**/*.php
do
   exec 4<"$php";read line <&4;exec 4<&-
   case "$line" in
     "<?"*) echo "found: $php"
   esac

done
    
por 18.03.2010 / 03:19
0
cat file.txt | head -1 | grep "^<?"

deve fazer o que você está pedindo.

    
por 12.03.2010 / 20:21
0

isto:

  % for i in *; do head -1 $i | grep "^<?" ; echo "$i : $?"; done

fornece algo assim:

  foo.xml: 0
  bla.txt: 1

todos os arquivos que não contiverem seu padrão serão "marcados" com "1". você pode brincar com isso até que atenda às suas necessidades.

    
por 12.03.2010 / 20:47
0

Deixe-me dar uma olhada nisso

find -type f | awk '
{
 if(getline ret < $0){
  if(ret~"^<\?$"){
   print "Good["$0"]["ret"]";
  }else{
   print "Fail["$0"]";
  };
 }else{
  print "empty["$0"]";
 };
 close($0);
}'

ninguém disse que wak não estava disponível: -)

    
por 14.07.2010 / 17:30