grep dosya başlangıcı?


10

Bir linux kabuğunda, belirli bir dosya setinin başlayacağından emin olmak istiyorum <?, başlangıçta bu tam dize ve başka karakter yok. "Dosya başlangıcı" nı ifade etmek için nasıl grep veya başka birini kullanabilirim?


Düzenleme: Bu joker karakter ve headaynı satırda bir dosya adı vermiyorum, bu yüzden grep zaman, filname görmüyorum. Ayrıca, "^<?"doğru sonuçları vermiyor gibi görünüyor; temelde bunu alıyorum:

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

Tüm dosyalar aslında iyi.

Yanıtlar:


11

Bash'ta:

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

Dosya olduklarından emin olun:

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


ve hepimiz çok bilgiç olduğumuz için: glob operatörünü çok sayıda dosya adında kullanmayın, bunun yerine kullanınfind
akira

kullanarak findda sadece düz dosyaları doğrudan boru başlatmak için dönebilirsiniz.
mpez0

1
Bunun readyerine kullanırken de tamamen headfor file in *; do [ -f "$file" ] || continue; read < "$file"; [[ "$REPLY" =~ ^\<\? ]] || echo "$file"; done
Bash'te yapabilirsiniz

4

Şunu yapın grep:

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

Dosya adlarını ayrıştırın:

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

3

Bunun için awk kullanabilirsiniz:

$ 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
$

3

Boş dosyalar dışında, bu Perl betiği çalışıyor gibi görünüyor:

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

Boş dosyaların nasıl işleneceğinden hemen emin değilim; Onlara ayrı bir özel durum olarak davranmaya cazip geleceğim:

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

2

Bunu dene

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

Bu, PHP ile biten her dosyanın bir listesini alır ve ardından döngüye girer. dosya adını yankılama ve ardından dosyanın ilk satırını yazdırma. Yeni ekledim

verecek çıktı gibi:

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

o zaman görmek istediğiniz şeyden kurtulmak ve sadece istisnalar bulmak için normal bir grep yapıştırabilirsiniz

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

çıktı:

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

4
Grep'in yararsız kullanımı; "find -name '* .php'" kullanın. Ayrıca, değişkenlerin tehlikeli kullanımı: "özel" dosya adlarıyla ilgili sorunlardan kaçınmak için "find -exec komutunu buraya '{}' '+'" kullanın. Bunun dışında her zaman değişkenlerinizi belirtin: "head -1" $ i "", "head -1 $ i" değil.
janmoesen

for x in *.php;do echo $x \"kafa -n1 $ x\";done
user23307

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

0
cat file.txt | head -1 | grep "^<?"

istediğini yapmalısın.


Evet, ancak joker karakter kullanırsam, bana dosya adları vermez :( Ayrıca "^ <?" Benim için çalışmadı, -v anahtarını kullandım.
user13743

2
@Phoshi Kompulsif catkullanım head -1 file.txt | grep "^<?"yeterlidir.
Benjamin Bannier

1
Kedinin yararsız kullanımı: - (((
vwegert

Yararsız kedi işe yaramaz :(
user13743 12:10

Her şeyi modüler ve bozuk tutarsanız komutları hatırlamanın çok daha kolay olduğunu düşünüyorum. Ben çalışacağım, commanddosyayı bir argüman olarak alıp alamayacağımı bilmiyorum . Kesinlikle gerekli olmayabilir, ama
çıkarmıyorum

0

bu:

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

size böyle bir şey verir:

  foo.xml: 0
  bla.txt: 1

deseninizi içermeyen her dosya "1" ile "işaretlenir". ihtiyaçlarınızı karşılayana kadar bununla oynayabilirsiniz.


1
Boşluk içerebiliyorsa dosya adlarını vermeniz gerekir. Ve muhtemelen 'grep' den / dev / null çıktısını kaybetmek istersiniz. Ayrıca kullanabilirsiniz: head -1 "$i" | grep '^<?' || echo "$i"bu yalnızca dosya adı sorunluysa yazdırılır.
Jonathan Leffler

2
"Grep -q" bunun içindir. :-)
janmoesen

0

Şuna bir bakayım

find -type f | awk '
{
 if (getline ret <$ 0) {
  if (ret ~ "^ <\\? $") {
   yazdır "İyi [" $ 0 "] [" ret "]";
  }Başka{
   yazdır "Başarısız [" $ 0 "]";
  };
 }Başka{
  "boş [" $ 0 "]" yazdır;
 };
 yakın ($ 0);
}'

kimse wak mevcut olmadığını söyledi :-)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.