ブロックのアドレスの後にsedコマンドをグループ化できないのはなぜですか?

ブロックのアドレスの後にsedコマンドをグループ化できないのはなぜですか?

sed特定のパターンを除くすべての行を印刷しようとしています。以下がうまくいかない理由を理解できません。

sed '/PATTERN/{d;q}' file

sedスクリプトについて私が理解したところによると、この式の結果は次のようになります。

  • 行が一致すると、/PATTERN/コマンドで構成されたグループを実行します。
    1. dパターンスペースの削除(=現在行)
    2. quit はその後、現在のパターン空間を印刷します。

孤立した状態で、2つの/PATTERN/d操作/PATTERN/q、つまりd問題のある行が削除され終了しますqsedしかし、ラインを印刷した後、文書化されているように。しかし、これら2つの操作をブロックに結合するとq無視されるようです。

Q代わりにGNU拡張として使用できることを知っていますが{d;q}(これは期待どおりに機能します!)、上記の内容がうまくいかない理由とドキュメントをどのように誤解したかを理解したいと思います。


私の実際のユースケースは、ファイルの最初の行が実際にパターンと一致し(いくつかの代替操作を実行した後)スキップするため(少し)複雑です。

sed -e '1{s/>21/>chr21/; n}' -e '/>/{d;q}' in.fasta >out.fasta

ただし、上記の単純化されたケースは同じ動作を示しています。

ベストアンサー1

特定のパターンが一致するまでファイルのすべての行を出力します。いいえ一致する行を出力するには、次のように使用できます。

sed -n '/PATTERN/q; p;' file

ここで、パターン空間のデフォルト出力は各サイクルの終わりに無効になります-n。代わりに各行を明示的に印刷しますp。指定されたパターンが一致すると処理を停止しますq

21fastaファイルの最初の行で染色体21の名前を変更し、chr21次のfastaヘッダー行に達するまでその染色体のDNAを抽出し続ける実際のより長いコマンドは、次のように書くことができます。

sed -n -e '1 { s/^>21/>chr21/p; d; }' \
       -e '/^>/q' \
       -e p <in.fasta >out.fasta

または

sed -n '1 { s/^>21/>chr21/p; d; }; /^>/q; p' <in.fasta >out.fasta

元の式の問題は、d新しいループを開始することです(つまり、次の行を強制的にパターン空間に読み込み、スクリプトの先頭にジャンプします)。これはq決して実行されないことを意味します。

GNU以外のシステムで構文を正確にするには、元のスクリプトは次のようになります/PATTERN/ { d; q; };後に追加される内容に注意してくださいq(スペースは重要ではありません)。

おすすめ記事