sedは空のファイルに対してコマンドを実行できます(終了コマンド)。

sedは空のファイルに対してコマンドを実行できます(終了コマンド)。

ファイルの内容を確認したいシェルスクリプトがあります。

予想されるコンテンツには、具体的な最初の行が必要です。例^MYFIRSTROW:そして空にできません。

だから私はGNUを使ってこのチェックを書きましたsed

#!/bin/bash

# "1q1": return 1 on input line 1. Only reached if the pattern did not match.
if sed -rn '/^MYFIRSTROW/q0; 1q1' myfile; then
   # ...
fi

しかし、空の入力でテストしましたが、sed1の代わりに0が返されました。

echo -ne '' | sed -rn '/^MYFIRSTROW/q0; 1q1'; echo $?
# 0

そして、この場合、アドレス「0」の使用方法が見つかりませんでした。

GNU sedで1つのコマンドでこれを行う方法はありますか?

注:代替ソリューション

私は主に空の入力に対してsedコマンドを実行できるかどうか、そしてどのように実行できるかについて答えたいのですが、私のエレガントなシェルスクリプトの提案は大歓迎です。

  • 私は遅いですが、これがif [ -s "myfile" ] && sed ...仕事を終えることができることに気づきました。

  • while read < myfileソリューションの使用を想像できますが、面倒そうです。

  • awkENDブロックが常に実行される反対の問題があったため、このコードは常に1を返しました。

    awk 'NR==1 && /^MYPATTERN/ {exit 0}END{exit 1}' myfile
    

PS:すみません。私の質問はコードゴルフリクエストに似ているようですが、私のスクリプトで簡潔で効率的なファイル内容を確認したいと思います。

答え1

主な答えは次のとおりです。いいえ。sed対応するスクリプトは行ごとに実行されるため、行がないとコマンドを実行できません。

回避策:今すぐシェルに行を追加してください。

sed -n '/^MYPATTERN/q;$q1;2q2' <(echo) yourfile

<(echo)空行が 1 つだけのファイルであるふりをするので、そのスクリプトはsed常に実行されます。空の場合、yourfile最初の行は最後の行でもあるため、$q1状態1で終了します。

それ以外の場合、スクリプトはの最初の行で実行されますyourfile。一致するものがあれば、ステータスコード0で終了します。

一致するものがない場合は存在し、sed状態は2です。追加されたラインファイルの最初の行はライン2として表示されますsed

kshスタイルのプロセス交換をサポートせずにシェルに対して同じ機能を達成する方法についてのヒントを提供したStéphane Chazelasに感謝します。

echo|sed -n '/^MYPATTERN/q;$q1;2q2' - yourfile

as-パラメータは、パイプから送信された空の行であるstdinを表しますecho

答え2

ENDAWKを使用すると、設定する終了コードをブロックに通知する変数を設定できます。ここでは、ok明示的に割り当てないとゼロという点を乱用します。 (またはBEGIN { ok=0 }露骨な内容を追加してください。)

awk 'NR==1 && /^MYPATTERN/ {ok=1; exit} NR==2 {exit} END {exit !ok}' myfile

これは意図的なものであり、ゴルフをした可能性が高いです。なぜなら、最初の行のパターンだけを探しているからです。


sedで簡単な方法でこれを行う方法がわかりません。これを逆にして表示された場合は1で終了できますが、MYPATTERN空のファイルの場合は0で終了する必要があります。その後、周囲の感覚を反転させる必要がありますif

if ! sed -Ene '/^MYPATTERN/q1; 1q0' myfile; then
    echo "MYPATTERN seen..."
fi

sedが読み取れないなどの実際のエラーを返しても、これはデフォルトのブランチに移動if(および印刷)されます。MYPATTERN seen...myfile

関連情報