sed または awk を使用した複数行文字列パターンの一致、挿入、削除

sed または awk を使用した複数行文字列パターンの一致、挿入、削除

デフォルトでは、入力コンピュータ、ユーザーなどの項目を追加する.ssh/configSSH管理ツールです。.ssh/config

質問:

のすべてのインスタンスを自動的に挿入または削除するために使用できるツール(たとえばsed、または)がありますか?awk複数行ひも?

たとえば、sed次のコマンドを使用します。

# inserts "stuff" in the line above "single-line-pattern" in file
sed -i.bkp "/single-line-pattern/i stuff" file

# inserts "stuff" in the line below "single-line-pattern" in file
sed -i.bkp "/single-line-pattern/a stuff" file

# removes all instances of "single-line-pattern" from file
sed -i.bkp "/single-line-pattern/d" file

考えられる解決策

パターンのすべてのインスタンスを削除するきちんとした解決策は、問題を元に戻し、インスタンス以外のすべてのアイテムを見つけて新しいファイルに印刷してから古いファイルを削除することです。アイテムの上に追加することを無視して(すべて削除したため)、固定された順序でファイルの末尾に追加しました。

しかし、これは上記の質問に対する答えではなく、そのようなツールや機能の例も提供しませsedawk複数行ひも。

私のソリューション

以下に私に合ったハッキースクリプトを示します。私はこれを使用しawk、複数行の問題を非常にうまく処理することがわかります。ただし、私が知っている限り、上記の例awkのように、このフレーズを操作または解決するために提供されるツールはあまりありません。sed

# create backup of file
cp $FILE $FILE.bak

# delete previous .tmp file
if [ -f $FILE.tmp ]; then
    rm $FILE.tmp
fi

# if the expression is not in the paragraph, append it to $FILE.tmp
awk -v RS="" -v expr1="Host $COMPUTER" -v expr2="Match originalhost \
$COMPUTER" -v user="User $USER" \
'{ if (! (($0 ~ expr1 || $0 ~ expr2) && $0 ~ user)) print$0 "\n"}' \
$FILE >> $FILE.tmp

mv $FILE.tmp $FILE

私の問題空間

$FILE以下に、andの$COMPUTER="compy"一致する段落セットを示します。$USER="harpo"別のコンピューター上のアイテムまたは同じコンピューター上の他のユーザーのアイテムを想像することができます(したがって、コンピューターとユーザーが一致することを確認)。

Match originalhost compy exec /usr/local/bin/superscript.sh
   HostName 192.168.0.101
   User harpo
   Port 22
   IdentityFile /home/harpo/.ssh/id_rsa

Host compy
   HostName 123.123.123.123
   User harpo
   Port 33
   IdentityFile /home/harpo/.ssh/id_rsa

ベストアンサー1

各段落の間にコメント記号を入れ、ファイルに他のコメント記号がないことを確認する方法。その後、awk段落全体を単一のレコードとしてRS="#"読み取るために使用して設定できます。awkこれを処理して確認し、後でファイルから目的のコンテンツ、方法、または末尾を出力(または出力しない)できます。ファイルの(awkENDアドレス指定子を使用)

更新:awk文書によると、この回答が機能するためにコメント記号がファイルの他の場所に存在しないことを要求する理由はありません。値がRS正規表現である可能性があるからです!

おすすめ記事