![ファイルのセクションを選択する](https://rvso.com/image/164701/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E3%82%BB%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%99%E3%82%8B.png)
次のような形式のファイルがあります:
title1
line
line
title2
line
line
line
title3
line
line
そして、その下のセクションを抽出しtitle2
てインデントを削除したいと思います。現在、私は次のように使用していますsed
(ただし、私のコンテキストでは またはシェル スクリプトが適していますが、残念ながらや のawk
ような言語は適していません)。perl
python
sed -n -e '/^title2$/,/^[a-zA-Z]/ { /^[a-zA-Z]/ d ; s/^[ \t]*// ; p }'
しかし、これでは最後に論理的に空白行が残ります (論理的には空白またはタブが含まれている可能性があるため)。これを取り除きたいのです。この部分には保持すべき他の論理的に空白の行があるかもしれないことに注意してください (または、a が/^[ \t]*$/ d
機能していたでしょう)。したがって、次の結果が望ましいです:
line
line
line
追加で実行できますsed -e '$d'
が、2 番目のプロセスを回避できるかどうかを知りたいです。
答え1
私はホールドスペースを使い、
sed -ne '/^title2$/,/^[a-zA-Z]/ { /^title2$/ { n; h; b; } ; /^[a-zA-Z]/ d; H; x; s/[ \t]*//; P; s/.*\n//; x }'
これは私が関心のあるケースを正しく処理しているようです。
答え2
- それが「純粋な」行(タブや白がない)である場合は、それも削除します。
/^$/
「論理的」な空白の使用
/^\s*$/
sed -n -e '/^title2:/,/^[a-zA-Z]/ { /^[a-zA-Z]/ d ; /^$/ d ; s/^[ \t]*// ; p }'
どこ
/^$/
行頭と行末を一致させる/^\s*$/
開始行、0 個以上のスペースまたはタブ、行末に一致
答え3
sed -n '/title2/,/^\S/ { //b; /^\s*$/ { N; /\n\S/q; P; D }; s/^\s*//; p }'
最初は@Archemarの注意を引くためにこれをやりました。もしよろしければお願いしますに返信この投稿への私のコメントお時間のあるときにいつでも。たとえ答えが「分かりません」でも構いません。ありがとうございます。
少なくとも私のbashシェルでは、 がなくても動作します-e
。なぜそれが必要なのか知りたいのですが。\s
または\S
[ \t]
はサポートされていない場合は、それぞれおよび に置き換えることができます[^ \t]
。
この質問を初めて見たとき、私と同じように何も知らなかった人のために説明します。
-n
自動印刷をオフにする/title2/,/^\S/
は検索範囲ですsed
(文字列「title2
」が最初に出現する行から、スペース以外の文字で始まる次の行まで[つまりtitle3
]包括的に){
囲まれたコマンドを指定した範囲またはパターンに適用することを意味します//b
次のコマンドが範囲の先頭と末尾に適用されないようにすることができます。
より文字通りに言うと、一致した場合、title2
または^\S
単にスクリプトの末尾に分岐した場合(b
)(ファイルに次の行が残っている場合は、それを処理します)GNUsed
(BSDA のも同様に述べていますが、他のバージョンがあるかどうかはわかりませんsed
。'//' は最後の正規表現の一致を繰り返します
/^\s*$/
範囲内の「論理的に空白の」行に一致します。{
N; /\n\S/q;
したがって、それが「論理的に空白」の行である場合、N
次の行をパターン スペースに追加し、その次の行が次のタイトルである場合は、処理を完全に終了する (q
) ため、「論理的に空白」の行も次のタイトルも印刷されません。P; D
「論理的に空白」の行の場合ない次のタイトルが続き、ただ「論理的に空白」の行が印刷され(P
)、その後ただ「論理的に空白の」行はパターンスペースから削除され、パターンスペースに追加された次の行がN
スクリプトの先頭から処理されるようになります(D
)
}
s/^\s*//; p
行頭のスペースとタブを削除し、フォーマットされた行を印刷します。
}
@Archemar お願いしますヘルプ