私が正しく理解している場合、あなたは次のことを望んでいます:
- 最初の 10 行に著作権表示がないファイルを検索し、
- それらのファイルに著作権表示を追加します。
さらに、次のことを行います。
- 最初の 10 行に著作権表示のあるファイルを検索し、
- 通知を標準テキストに更新します。
これらの 2 つのタスクは、1 つのセットにまとめることができるように思えます。
- 最初の 10 行にある既存の著作権表示を削除してから、
- 新しい著作権表示をファイルに挿入します。
質問に対するコメントに入力したサンプルテキストの短縮バージョンが有効であり、たとえば各ファイルの 2 行目に挿入する必要があると安全に想定できる場合、次の場合、要件の最初のセットを達成する必要があります。あなたはGNU sedを使用しています:
find . -type f -not -exec grep -q Copyright {} \; -exec sed -i'' '2i/* Copyright */' {} \;
GNU sed を実行していない場合(つまり、FreeBSD、OSX、Solaris などを使用している場合)、sed スクリプトが異なるため、お知らせください。
これはどのように機能しますか?
find
コマンドは次のオプションを取得しています。
-type f
ディレクトリやデバイスではなく、ファイルのみを見るように指示します。
-not
次のオプションを反転します。
-exec grep -q Copyright {} \;
著作権が含まれているものに検索を制限します (によって変更されました-not
)
-exec sed -i'' '2i/* Copyright */' {} \;
著作権表示を挿入します。
sed スクリプトによって解釈される特殊文字を著作権表示に含めたい場合、この解決策は困難になる可能性があります。しかし、それはあなたの質問に答えます。:)
代わりに、改訂された要件を処理したい場合、つまり既存の著作権表示を最初に削除したい場合は、2 つのワンライナーでこれを行うことができます。
まず、既存の著作権表示を削除します。
find . -type f -exec sh -c 'head {} | grep -q Copyright' \; -exec sed -ne '10,$ta;/Copyright/d;:a;p' {} \;
サブディレクトリを再帰的にトラバースしたい場合を除いて、これは少し冗長かもしれません。これfind
はデフォルトで行われます。sed スクリプトは、最初の 10 行に著作権情報がないファイルに対しては何も実行しないため、すべてのファイルが 1 つのディレクトリにある場合は、代わりに次のスクリプトも機能するはずです。
for file in *;do sed -ne '10,$ta;/Copyright/d;:a;p' "$file"; done
次に、新しいものを再び追加します。
for file in *;do sed -i'' '2i/* Copyright */' "$file"; done
または、サブディレクトリを介して再帰的にこれを行いたい場合:
find . -type f -exec sed -i'' '2i/* Copyright */' {} \;
最終更新:
この後、これ以上の時間を費やすことはできません。
find . -type f \
-exec sh -c 'head {} | grep -q Copyright' \; \
-exec sed -ne '1h;1!H;${;g;s:/\*.*Copyright.*\*/:/* Copyright 1998-2012 */' {} \;
何?
1 つ目-exec
は、ファイルの最初の 10 行で "Copyright" という単語を検索します。上記の最初に投稿した例と同じように。grep が何かを見つけた場合、この条件は true を返します。
2番目-exec
は置換を行います。ファイル全体を sed のホールド バッファに読み込みます。次に、ファイルの最後に到達すると、( g
) ホールド バッファーが考慮され、( s
) 複数行の置換が行われます。
これには何らかの調整が必要になる可能性が非常に高く、ファイルの他の場所にコメントがある場合はまったく機能しない可能性があることに注意してください。GNU sed が貪欲でないスターをサポートしているかどうかは思い出せません。あなたはそれを自分で研究することができます。
これが私のテストです:
$ printf 'one\n/* Copyright blah blah\n *\n */\ntwo\n' | sed -n '1h;1!H;${;g;s:/\*.*Copyright.*\*/:/* Copyright 1998-2012 */:g;p;}'
one
/* Copyright 1998-2012 */
two
これは既存の著作権情報を維持しませんが、少なくとも複数行の問題に対処します.