
file.php
次のファイルがあります()。
...
Match user foo
ChrootDirectory /NAS/foo.info/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
Match user bar
ChrootDirectory /NAS/bar.co.uk/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
Match user baz
ChrootDirectory /NAS/baz.com/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
段落の1つを削除するためにbashスクリプトを作成しようとしています。
foo
でスクリプトを実行したいとしましょうfile.php
。
...
Match user bar
ChrootDirectory /NAS/bar.co.uk/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
Match user baz
ChrootDirectory /NAS/baz.com/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
どうすればいいですか?使い方を考えましたが、sed
ライナーひとつだけフィットしていると思いますか?
sed -i 's/foo//g' file.php
段落のほとんどの行は一意ではないため、すべての行に対してこれを行うことはできません!どんなアイデアがありますか?
答え1
実際にsed
範囲を選択することもできます。このコマンドは、Match user foo
最初の空白行(含む)間のすべての行を削除します。
$ sed '/Match user foo/,/^\s*$/{d}' file
Match user bar
ChrootDirectory /NAS/bar.co.uk/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
Match user baz
ChrootDirectory /NAS/baz.com/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
しかし、個人的には、先行の-00
空行を削除する利点があるPerlの短絡モード()を使用してこれを行います。
$ perl -00ne 'print unless /Match user foo/' file
Match user bar
ChrootDirectory /NAS/bar.co.uk/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
Match user baz
ChrootDirectory /NAS/baz.com/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
どちらの場合も、-i
ファイルの内部編集を使用できます(これにより、元のファイルのバックアップが作成されますfile.bak
)。
sed -i.bak '/Match user foo/,/^\s*$/{d}' file
または
perl -i.bak -00ne 'print unless /Match user foo/' file
答え2
terdonの答えより少し複雑ですsed
。
awk '/foo/ {suppress=1} /^\s*$/ {suppress=0} !suppress' file.php
terdonの答えとほぼ同じ結果を生成します。
...
Match user bar
ChrootDirectory /NAS/bar.co.uk/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
Match user baz
ChrootDirectory /NAS/baz.com/
ForceCommand internal-sftp
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
つまり、一致する行から始まるすべてのfoo
行を削除(抑制)します。到着スペースのみを含む最初の後続行。入力ファイルの8行、9行、10行file.php
(user foo
との間)user bar
は空で、出力に表示されます。対照的に、terdonの答えは、一致する行で始まるfoo
すべての行を削除します。渡す最初の後続の行には空白のみが含まれているため、8行は削除されますが、9行と10行は残ります。
これはまさにユーザーが要求するものではありません。
awk '/foo/ {suppress=1}
/^\s*$/ && suppress==1 {suppress=2}
/[^\s]/ && suppress==2 {suppress=0}
!suppress' file.php
はい。 (読みやすくするために複数行に分けて1行に入力できます。)これを検出すると、抑制モード#1()foo
に入ります。suppress=1
サプレッションモード#1に空白行が表示されると、サプレッションモード#2に切り替わる。サプレッションモード#2に空白以外の行が表示されている場合は、モード0に切り替わります。最後に、これは明らかなタスクを実行します。つまり、suppress
編集されていない行を印刷します。