Bashスクリプトのテキストファイルの中央に1行のテキストを追加しようとしています。具体的には、ネームサーバーを/etc/resolv.confファイルに追加しようとしています。現状では、resolv.confは次のようになっています。
# Generated by NetworkManager
domain dhcp.example.com
search dhcp.example.com
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3
私の目標はnameserver 127.0.0.1
他のすべてのネームサーバー行の上、ただしその上のテキストの下。最後に、resolve.confファイルを次のようにしたいと思います。
# Generated by NetworkManager
domain dhcp.example.com
search dhcp.example.com
nameserver 127.0.0.1
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3
これは、bashスクリプトを介してどのように可能ですか?これはsedまたはawkでできることですか?または、ファイルを再作成するための創造的なグレーピングは私の最高の動きでしょうか?
Sedを使用したソリューションは次のとおりです。
$ sed -n 'H;${x;s/^\n//;s/nameserver .*$/nameserver 127.0.0.1\n&/;p;}' resolv.conf
# Generated by NetworkManager
domain dhcp.example.com
search dhcp.example.com
nameserver 127.0.0.1
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3
仕組み:最初に、-n
フラグでsedの出力を抑制します。次に、各行について、行をホールドスペースに追加し、改行で区切ります。
H
ファイルの最後に来たら($
で指定)、ホールドスペースの内容をパターンスペースに移動します。
x
パターンスペースの最初の行が空白の場合、何も置き換えません。
s/^\n//
次に、nameserver
で始まる最初の行を、新しい行であるnameserver 127.0.0.1
を含む行に置き換えます(お使いのバージョンのsed
は、\n
をサポートしていない場合があります。 n
とリテラルの改行)および元の行(&
で表される):
s/nameserver .*$/nameserver 127.0.0.1\n&/
結果を印刷するだけです。
p
search
行の直後に挿入する場合、これははるかに簡単です。
sed -ie '/^search/a nameserver 127.0.0.1' filename
-i
:ファイルをその場で編集-e
:sed式内のスクリプト/コマンドの実行を許可しますa mynewtext
:マッチしたパターンの後にテキストmynewtextを挿入するようにsedに指示するコマンドawk '/^nameserver/ && !modif { printf("INSERT\n"); modif=1 } {print}'
次のようなものはどうですか:
sed -e ':a;N;$!ba;s/nameserver/nameserver 127.0.0.1\nnameserver/' /etc/resolv.conf
(これと同様: sed:2行にわたってパターンを検索し、そのパターンの後に置換しない )
Perlソリューションは次のとおりです。
Perl -lne 'if (not $f and /^nameserver/){ print "nameserver 127.0.0.1"; $f=1 }; print' resolv.conf
-n
入力ファイルのすべての行をループし、すべての行を自動的に印刷しません
-l
は、処理前に改行を削除し、後でそれらを追加します
-e
Perlコードを実行します
$f
は、ネームサーバー文字列がすでに見つかったことを示すフラグとして使用されます
これはあなたのために働くかもしれません:
sed -e '/nameserver/{x;/./b;x;h;i\nameserver 127.0.0.1' -e '}' resolv.conf
またはGNU sed:
sed -e '0,/nameserver/{//i\nameserver 127.0.0.1' -e '}' resolv.conf