文字列で始まるディレクトリ内のすべてのファイルを見つけて印刷するには、シェルスクリプトを作成する必要があります#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}' *