web-dev-qa-db-ja.com

sedを使用して最初の試合の後に行を挿入する

どういうわけか私はこれに対する直接的な答えを見つけることができないようで、私は現時点でちょっと時間がかかり過ぎています。 sedコマンドを使用して、特定の文字列に一致する最初の行の後にテキストの選択行を挿入する方法を説明します。私は持っています ...

CLIENTSCRIPT="foo"
CLIENTFILE="bar"

そしてCLIENTSCRIPT=行の後に行を挿入したいのですが….

CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"
210
user2150250

GNU sedを使用してこれを試してください。

sed '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file

をその場で置き換えたい場合は

sed -i '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file

出力

CLIENTSCRIPT="foo"
CLIENTSCRIPT2="hello"
CLIENTFILE="bar"

Doc

  • sed doc を参照して\aを検索してください(追加)
335
Gilles Quenot

標準的なsed構文に注意してください(POSIXの場合と同様に、(GNU、OS/X、BSD、Solarisなど)のすべての準拠sed実装でサポートされています)。

sed '/CLIENTSCRIPT=/a\
CLIENTSCRIPT2="hello"' file

または一行で:

sed -e '/CLIENTSCRIPT=/a\' -e 'CLIENTSCRIPT2="hello"' file

-expressions(および-filesの内容)は、sedスクリプトのsedが解釈するように改行で結合されています)。

インプレース編集のための-iオプションもGNU拡張です。他の実装(FreeBSDのような)のいくつかはそのために-i ''をサポートします。

代わりに、移植性のために、代わりにPerlを使うことができます。

Perl -pi -e '$_ .= qq(CLIENTSCRIPT2="hello"\n) if /CLIENTSCRIPT=/' file

あるいはedまたはexを使用することもできます。

printf '%s\n' /CLIENTSCRIPT=/a 'CLIENTSCRIPT2="hello"' . w q | ex -s file
43

sコマンドを使用したPOSIX準拠のもの

sed '/CLIENTSCRIPT="foo"/s/.*/&\
CLIENTSCRIPT2="hello"/' file
12
SLePort

MacOS(少なくともOS 10)でもUnixでも同じように動作するSedコマンド(つまりGillesの(現在受け入れられている)のようなgnu sedは必要ありません)。

sed -e '/CLIENTSCRIPT="foo"/a\'$'\n''CLIENTSCRIPT2="hello"' file

これはbashや、$ '\ n'評価引用スタイルを知っている他のシェルでも動作します。すべて1行にまとめて、古い/ POSIX sedコマンドで機能させることができます。 CLIENTSCRIPT = "foo"(または同等のもの)に一致する行が複数ある可能性があり、最初に追加行のみを追加したい場合は、次のように書き直すことができます。

sed -e '/^ *CLIENTSCRIPT="foo"/b ins' -e b -e ':ins' -e 'a\'$'\n''CLIENTSCRIPT2="hello"' -e ': done' -e 'n;b done' file

(これにより、行挿入コードの後に​​、ファイルの残りの部分を循環するだけのループが作成され、最初のsedコマンドに戻ることはありません)。

その行がコメントに表示される、またはインデントされている場合に備えて、マッチングパターンに '^ *'を追加したことに気付くかもしれません。 100%完璧というわけではありませんが、ありがちな他の状況をカバーしています。必要に応じて調整してください...

これらの2つの解決策は、新しい挿入された行がエスケープされていないバックスラッシュやアンパサンドを含む場合、それらがsedによって解釈され、\nのように同じ結果にならないという問題を回避します。 。 \0は最初に一致した行です。特に、以前に$ {var //}を使用して最初にすべてをエスケープする必要がある場合、または別のsedステートメントなどから変数から来る行を追加する場合は特に便利です。

あなたが例えば、関数内で、行頭にaコマンドの置換テキストを置きたくない場合、この解決策はスクリプト内で少し面倒です(ただし、引用符と\ nは読みにくいですが)。インデント行私は$ '\ n'がシェルによって改行に評価されることを利用しました、それは通常の '\ n'一重引用符で囲まれた値ではありません。

私はPerlやawkでさえももっと読みやすいので勝つかもしれないと思っていますが、それは十分に長くなっています。

5
Breezer

私は最近、これに対処しなければなりませんでしたが、1つのファイルだけでなく、手作業ではできなかった複数の異なるファイルを扱う必要がありました。だから私はそれのためのスクリプトを見つけなければなりませんでした。

スクリプトのダウンロード: kinglazy-autoinsert.sh

使用法:

kinglazy-autoinsert.sh(list_file)(pattern_file)

パラメーターの説明:

list_file =これは編集したいファイルのリストの絶対パスを含むファイルです。

pattern_file =これは、新しいテキストを追加したいパターン(最初の列)を指定するファイルです。パターンの下に追加する新しいテキストは、2列目に指定されています。そしてそれはそれについてです!

このスクリプトは時間を節約し、最小限の労力で仕事を終わらせるのに役立ちます。

依存関係:なし

0
Blessed

私は似たような仕事をしていましたが、上記のPerlソリューションをうまく動かすことができませんでした。

これが私の解決策です:

Perl -i -pe "BEGIN{undef $/;} s/^\[mysqld\]$/[mysqld]\n\ncollation-server = utf8_unicode_ci\n/sgm" /etc/mysql/my.cnf

説明:

私の/etc/mysql/my.cnfファイルの中で[mysqld]のみを含み、次の文字列で置き換えられた行を検索するために正規表現を使用します。

[mysqld] collation-server = utf8_unicode_ci

collation-server = utf8_unicode_ciを含む行の後に[mysqld]行を効果的に追加します。

0
Caleb

Awkバリアント:

awk '1;/CLIENTSCRIPT=/{print "CLIENTSCRIPT2=\"hello\""}' file
0
Corentin Limier

これに対する答えを投稿するのに少し遅れるかもしれませんが、私は上記の解決策のうちのいくつかが少し面倒であると感じました。

私はsedで単純な文字列置換を試みました、そしてそれはうまくいきました:

sed 's/CLIENTSCRIPT="foo"/&\nCLIENTSCRIPT2="hello"/' file

記号は一致した文字列を反映しているので、\ nと新しい行を追加します。

前述のとおり、その場でそれを実行する場合は、次のようにします。

sed -i 's/CLIENTSCRIPT="foo"/&\nCLIENTSCRIPT2="hello"/' file

別物。式を使用して一致させることができます。

sed -i 's/CLIENTSCRIPT=.*/&\nCLIENTSCRIPT2="hello"/' file

これが誰かに役立つことを願っています

0
siwesam