シェルを使用してbash
次の行を含むファイルから
first "line"
<second>line and so on
1つ以上の項目を毎回次に"line"\n<second>
変更したいと思います。other characters
first other characters line and so on
"
したがって、文字列を同じ特殊文字に置き換え、<
改行文字に置き換える必要があります。
他の答えから検索した後、sed
コマンドの右側(したがって文字列other characters
)では改行を許可できますが、左側では許可されていません。
どのような方法がありますか(よりこれ)sed
この結果を得るにはgrep
?
答え1
まあ、私はいくつかの簡単な方法を考えることができますがgrep
(とにかく交換を行いません)またはsed
。
パール
変える各
"line"\n<second>
が表示されたら、other characters
以下を使用してください。$ perl -00pe 's/"line"\n<second>/other characters /g' file first other characters line and so on
または、複数の連続した発生を1つとして扱い、
"line"\n<second>
すべて単一の項目に置き換えるには、次のようにother characters
します。perl -00pe 's/(?:"line"\n<second>)+/other characters /g' file
例:
$ cat file first "line" <second>"line" <second>"line" <second>line and so on $ perl -00pe 's/(?:"line"\n<second>)+/other characters /g' file first other characters line and so on
これ
-00
により、Perlは「ショートモード」でファイルを読み込みます。つまり、「行」\n\n
がと定義され、\n
本質的に各段落が 1 行に処理されるという意味です。したがって、交換は改行全体で一致します。アッ
$ awk -v RS="\n\n" -v ORS="" '{ sub(/"line"\n<second>/,"other characters ", $0) print; }' file first other characters line and so on
基本的なアイデアは同じです。レコード区切り記号(
RS
)を設定して\n\n
ファイル全体を削除し、出力レコード区切り文字を空白に設定し(それ以外の場合は追加の改行が印刷されます)、この関数を使用してsub()
それを置き換えます。
答え2
ファイル全体を読み、グローバル置換を実行します。
sed -n 'H; ${x; s/"line"\n<second>/other characters /g; p}' <<END
first "line"
<second> line followed by "line"
<second> and last
END
first other characters line followed by other characters and last
答え3
3つの異なるsed
コマンド:
sed '$!N;s/"[^"]*"\n<[^>]*>/other characters /;P;D'
sed -e :n -e '$!N;s/"[^"]*"\n<[^>]*>/other characters /;tn'
sed -e :n -e '$!N;/"$/{$!bn' -e '};s/"[^"]*"\n<[^>]*>/other characters /g'
3つすべてが基本的なs///
代替コマンドに基づいて構築されました。
s/"[^"]*"\n<[^>]*>/other characters /
彼らはまた、最後の行に注意を払うよう努めます。なぜなら、sed
出力が極端な場合に変わる傾向があるからです。これが意味するのは、$!
最後の行ではなくすべての行のアドレスを一致させることです。!
$
また、両方ともextコマンドを使用して、N
パターンスペースの\n
ewline文字に次の入力行を追加します。sed
しばらくこの文字を使ってきた人なら誰でも\n
ewline文字に依存する方法を学びます。それを得る唯一の方法は、明示的にそこに置くことです。
3 つすべてのアクションを取る前に、できるだけ少ない入力を読み取ろうとします。アクションをsed
実行する前に、入力ファイル全体を読む必要なく、できるだけ早くアクションを実行してください。
すべてそうですが、N
3つすべてが異なる再帰方法を持っています。
最初のコマンド
最初のコマンドは非常に単純なN;P;D
ループを使用します。これら3つのコマンドはPOSIX準拠のコマンドに組み込まれており、sed
お互いをよく補完します。
N
- 前述のように挿入された改行区切り記号のN
後のパターンスペースに追加の入力行を追加します。\n
P
-p
;同様に、P
パターンスペースを印刷しますが、最初に表示される\n
ewline文字のみを印刷します。したがって、次の入力/コマンドが提供されます。printf %s\\n one two | sed '$!N;P;d'
sed
P
印刷のみ可能一つ。しかし...D
- 同様にd
;D
パターン空間を削除し、別のラインループを開始します。同じではないd
、パターン空間で最初に現れるewlineD
のみが削除されます。 ewline 文字の後のパターン空間にさらに多くのコンテンツがある\n
場合、残りのコンテンツは次の行ループを開始するために使用されます。たとえば、前の例で a を置き換えると、次も印刷されます。\n
sed
d
D
sed
P
一つそして二つ。
このコマンドは次の行でのみ繰り返されます。欲しくないs///
交換ドアを一致させます。置換は追加された改行をs///
削除するため、パターンスペースを削除しても何も残りません。\n
N
sed
D
P
および/またはを選択的に適用するためにテストを実行できますが、D
この戦略に適した他のコマンドがあります。これは、一致する連続行のみを処理するように再帰が実装されたためです。部分連続ラインシーケンスマッチングの代替規則両端選択肢はs///
うまくいきません。
次の入力が与えられた場合:
first "line"
<second>"line"
<second>"line"
<second>line and so on
...印刷されます...
first other characters "line"
<second>other characters line and so on
しかしそれは扱います
first "line"
second "line"
<second>line
...まさに。
2番目の順序
このコマンドは3番目のコマンドと非常によく似ています。どちらも:b
ranch/ t
est タグを使用します。(Joseph R.の答えもこれを証明します。ここ)特定の条件が与えられると、再帰的に戻ります。
-e :n -e
– 移植可能なスクリプトは、ewline または新しいインライン実行文を使用してsed
ラベル定義を区別します。:
\n
-e
:n
- というラベルを定義しますn
。あなたはいつでもbn
このコンテンツを使用または再帰することができますtn
。
tn
–t
est コマンドは指定されたラベルを返します。(または提供されていない場合は、現在の行サイクルのスクリプトを終了します)s///
最後の呼び出し以降にカスタムタグまたは置換項目がある場合は、成功したと見なされt
ます。
このコマンドは一致する行を繰り返します。sed
パターンを次に正常に変更すると、その他の役割、ラベルsed
に戻ってもう一度やり直してください。交換が行われない場合は、:n
パターンスペースが自動的に印刷され、次のラインサイクルが始まります。s///
sed
これは連続したシーケンスをよりよく処理する傾向があります。最後に失敗した場合は、以下を印刷します。
first other characters other characters other characters line and so on
3番目の注文
前述のように、ここのロジックは以前のロジックと非常に似ていますが、テストはより明確です。
/"$/bn
- これはsed
テストです。 ranchコマンドはそのアドレスの関数なので、b
ewlineが追加され、パターンスペースがまだ二重引用符で終わるまで、ranchは返されませsed
んb
。:n
\n
"
N
との間にできるだけ少ない作業を行いますb
。これにより、sed
次の行がルールと一致しないようにするために必要な正確な入力を非常に迅速に収集できます。交換はグローバルフラグをs///
使用する点で異なりますg
。したがって、必要なすべての交換を一度に実行します。同じ入力が与えられると、このコマンドの出力は前のコマンドと同じです。
答え4
これはバリエーションですグレンの答え連続して複数回発生した場合に動作します(sed
GNUのみ)。
sed ':x /"line"/N;s/"line"\n<second>/other characters/;/"line"/bx' your_file
これは:x
支店のラベルです。基本的にこれが行うことは、置き換えられた行を確認し、まだ一致する場合はラベル"line"
に分岐:x
し(これがまさにそれですbx
)、バッファに別の行を追加して処理を開始することです。