grepファイルの先頭?


10

Linuxシェルでは、特定のファイルセットがすべてで始まり<?、正確な文字列があり、先頭に他の文字がないことを確認します。「次で始まるファイル」を表現するために、grepや他の方法を使用するにはどうすればよいですか?


編集:これをワイルドカード化してheadおり、同じ行にファイル名を指定していません。そのため、grepすると、filnameが表示されません。また、"^<?"正しい結果が得られないようです。基本的に私はこれを手に入れています:

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

すべてのファイルは実際に良好です。

回答:


11

バッシュで:

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

それらがファイルであることを確認してください:

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


私たちはすべてのように知識をひけらかすされているので:代わりに、filesnamesの膨大な量のグロブ演算子を使用していない使用find
アキラ

使用してfindも、パイプを開始するためにのみ直接プレーンファイルを返すことができます。
mpez0

1
使用するときは、完全にバッシュでそれを行うことができますread代わりにhead、あまりにも、: for file in *; do [ -f "$file" ] || continue; read < "$file"; [[ "$REPLY" =~ ^\<\? ]] || echo "$file"; done
janmoesen

4

してくださいgrep

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

ファイル名を解析します。

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

3

これにはawkを使用できます。

$ 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

空のファイルを除いて、このPerlスクリプトは動作するようです:

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

空のファイルの処理方法はすぐにはわかりません。それらを別の特別なケースとして扱いたくなります。

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

2

これを試して

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

これは、PHPで終わるすべてのファイルのリストを取得し、それをループします。ファイル名をエコーし​​てから、ファイルの最初の行を出力します。挿入したばかり

次のような出力が得られます:

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

次に、最後に通常のgrepを貼り付けて、見たいものを取り除き、例外だけを見つけることができます

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

出力:

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

4
grepの無用な使用; 「find -name '* .php'」を使用します。また、変数の危険な使用:「find -exec your command here '{}' '+'」を使用して、「特殊な」ファイル名の問題を回避します。それとは別に、常に変数を引用してください:「head -1 $ i」ではなく、「head -1 "$ i"」。
janmoesen 2010年

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

1

バッシュ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 "^<?"

あなたが求めていることをすべきです。


私はそれワイルドカード場合うん、しかし、それは私がファイル名:(も与えるものではありません。私のために仕事はしなかった、私は-vスイッチを使用し、「^ <?」。
user13743

2
@Phoshi強迫的なcat使用法でhead -1 file.txt | grep "^<?"十分です。
Benjamin Bannier

1
猫の無駄な使用: - (((
vwegert

役に立たない猫は役に立たない:(
user13743

すべてをモジュール化して分解すると、コマンドを覚えておく方がはるかに簡単になります。私は知っている-動作しcommandますが、ファイルを引数として取るかどうかはわかりません。厳密には必要ないかもしれませんが、私はそれを取り出していません:)
Phoshi

0

この:

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

このようなものを与えます:

  foo.xml: 0
  bla.txt: 1

パターンを含まないすべてのファイルは「1」でマークされます。それがあなたのニーズに合うまでそれで遊ぶことができます。


1
ファイル名にスペースが含まれる可能性がある場合は、ファイル名を引用する必要があります。そして、おそらく 'grep'から/ dev / nullへの出力を失いたくなるでしょう。また、次のように使用することもできhead -1 "$i" | grep '^<?' || echo "$i"ます。問題がある場合にのみファイル名を出力します。
ジョナサンレフラー

2
これが「grep -q」の目的です。:-)
janmoesen

0

これでやってみよう

find -type f | awk '
{
 if(getline ret <$ 0){
  if(ret〜 "^ <\\?$"){
   print "Good [" $ 0 "] [" ret "]";
  }そうしないと{
   印刷 "失敗[" $ 0 "]";
  };
 }そうしないと{
  "empty [" $ 0 "]"を出力;
 };
 close($ 0);
} '

wakが利用できないと誰も言っていません:-)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.