ファイルの最初の行に特定の文字列が含まれているかどうかを確認するには? [コピー]

ファイルの最初の行に特定の文字列が含まれているかどうかを確認するには? [コピー]

文字列で始まるディレクトリ内のすべてのファイルを見つけて印刷するには、シェルスクリプトを作成する必要があります#include。これで、ファイルに文字列があるかどうかを確認する方法がわかりました。

for f in `ls`; do
    if grep -q 'MyString' $f; then:
        #DO SOMETHING
    fi

しかし、最初の行にどのように適用できますか?最初の行の変数を作成し、それが起動していることを確認しようとしましたが、#includeこれを行う方法がわかりません。コマンドを試しましたが、read変数を読み取れませんでした。

この問題を解決する別の方法を聞きたいです。とにかく、最初の行が#include文字列を含むのではなくで始まることを確認する必要があることに注意してください。これが私が次の問題を見つけた理由です。最初の行が特定のパターンと一致する場合にのみファイルの内容を印刷する方法は? https://stackoverflow.com/questions/5536018/how-to-print-matched-regex-pattern-using-awk 彼らはまったく役に立ちませんでした。

答え1

最初の行がsedで始まることを確認するのは簡単です#include(GNUとAT&T)。

sed -n '1{/^#include/p};q'   file

または単純化(およびPOSIX互換):

sed -n '/^#include/p;q'   file

#includeファイルが最初の行に含まれている場合にのみ出力されます。これにより、最初の行だけを読んで確認できるため、非常に高速になります。

したがって、すべてのファイルのシェルループ(sedを使用)は次のようになります。

for file in *
do
    [ "$(sed -n '/^#include/p;q' "$file")" ] && printf '%s\n' "$file"
done

もしpwdにはファイルのみがあります(ディレクトリなし)。

ファイルのすべての行を印刷する必要がある場合は、公開された最初のコード(GNUおよびAT&Tバージョン)と同様のソリューションを使用できます。

sed -n '1{/^#include/!q};p'  file

または(BSD互換POSIXバージョン):

sed -ne '1{/^#include/!q;}' -e p  file

または:

sed -n '1{
           /^#include/!q
         }
         p
       '  file

答え2

for file in *; do
  [ -f "$file" ] || continue
  IFS= read -r line < "$file" || [ -n "$line" ] || continue
  case $line in
    ("#include"*) printf '%s\n' "$file"
  esac
done

ファイル名の代わりにファイルの内容を印刷するprintfコマンドをcat < "$file"

awk拡張機能をサポートnextfileし、非一般的なファイルを開くときに発生する可能性のある副作用を気にしない場合:

awk '/^#include/{print substr(FILENAME, 3)}; {nextfile}' ./*

上に私たちは文字を含むファイル名(または名前という名前のファイル名)に関連する問題を回避する./ために、後で削除するプレフィックスを追加します。FILENAME=-

代わりに、通常のファイル(または上記のように通常のファイルへのシンボリックリンク)をに渡すzshことができます。./*./*(-.)[ -f ... ]awk

または、名前の代わりにファイルの内容を印刷します。

awk 'FNR == 1 {found = /^#include/}; found' ./*

(これはポータブルです)。

答え3

for file in *
do
  [ -f "$file" ] && head -n 1 < "$file" | grep -q '^#include' && cat < "$file"
done

-qこのオプションを有効にすると、エラーgrepが発生してもゼロ状態で終了します。

答え4

この質問は、bashとsedのソリューションが非常に複雑ですが(GNU)awkを使用すると、作業がはるかに簡単になる完璧な例です。

gawk 'FNR==1 && /^#include/{print FILENAME}{nextfile}' *

関連情報