takashi kono's blog

コーヒーとキーボードと共に何かを記録していくブログ

sed の便利な使い方備忘録

目的

sed の便利な使い方を備忘録として残す

目次

version

コンテナの中なので root 何だけど、許して(ぇ

root@nextcloud1:~# sed --version
sed (GNU sed) 4.8
Packaged by Debian
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Jay Fenlason, Tom Lord, Ken Pizzini,
Paolo Bonzini, Jim Meyering, and Assaf Gordon.

This sed program was built with SELinux support.
SELinux is disabled on this system.

GNU sed home page: <https://www.gnu.org/software/sed/>.
General help using GNU software: <https://www.gnu.org/gethelp/>.
E-mail bug reports to: <bug-sed@gnu.org>.
root@nextcloud1:~#

指定行にインサート

4行目にインサート

root@nextcloud1:~# cat -n test
     1  foo
     2  ;bar
     3  ;memory_limit
     4
     5  nyaa
     6  pen
     7  #pineapple
     8  apple
     9  pen
    10
root@nextcloud1:~#
root@nextcloud1:~# sed '4imemory_limit' test
foo
;bar
;memory_limit
memory_limit

nyaa
pen
#pineapple
apple
pen

root@nextcloud1:~# sed '4imemory_limit' test -i
root@nextcloud1:~#
root@nextcloud1:~# cat -n test
     1  foo
     2  ;bar
     3  ;memory_limit
     4  memory_limit
     5
     6  nyaa
     7  pen
     8  #pineapple
     9  apple
    10  pen
    11
root@nextcloud1:~#

指定行を削除

4 行目を削除

root@nextcloud1:~# cat -n test
     1  foo
     2  ;bar
     3  ;memory_limit
     4  memory_limit
     5
     6  nyaa
     7  pen
     8  #pineapple
     9  apple
    10  pen
    11
root@nextcloud1:~#
root@nextcloud1:~#
root@nextcloud1:~# sed '4d' test
foo
;bar
;memory_limit

nyaa
pen
#pineapple
apple
pen

root@nextcloud1:~# sed '4d' test -i
root@nextcloud1:~#
root@nextcloud1:~# cat -n test
     1  foo
     2  ;bar
     3  ;memory_limit
     4
     5  nyaa
     6  pen
     7  #pineapple
     8  apple
     9  pen
    10
root@nextcloud1:~#

指定行の ; を削除

3 行目の ; を削除

root@nextcloud1:~# cat -n test
     1  foo
     2  ;bar
     3  ;memory_limit
     4
     5  nyaa
     6  pen
     7  #pineapple
     8  apple
     9  pen
    10
root@nextcloud1:~#
root@nextcloud1:~#
root@nextcloud1:~# sed '3s/;//' test
foo
;bar
memory_limit

nyaa
pen
#pineapple
apple
pen

root@nextcloud1:~# sed '3s/;//' test -i
root@nextcloud1:~#
root@nextcloud1:~# cat -n test
     1  foo
     2  ;bar
     3  memory_limit
     4
     5  nyaa
     6  pen
     7  #pineapple
     8  apple
     9  pen
    10
root@nextcloud1:~#

指定行の行頭に ; をインサート

3 行目の行頭に ; をインサート

root@nextcloud1:~# cat -n test
     1  foo
     2  ;bar
     3  memory_limit
     4
     5  nyaa
     6  pen
     7  #pineapple
     8  apple
     9  pen
    10
root@nextcloud1:~#
root@nextcloud1:~# sed '3s/^/;/' test
foo
;bar
;memory_limit

nyaa
pen
#pineapple
apple
pen

root@nextcloud1:~#
root@nextcloud1:~# sed '3s/^/;/' test -i
root@nextcloud1:~#
root@nextcloud1:~# cat -n test
     1  foo
     2  ;bar
     3  ;memory_limit
     4
     5  nyaa
     6  pen
     7  #pineapple
     8  apple
     9  pen
    10
root@nextcloud1:~#

行頭に # を挿入

5 行目の行頭に # を挿入

root@nextcloud1:~# cat -n test
     1  foo
     2  ;bar
     3  ;memory_limit
     4
     5  nyaa
     6  pen
     7  #pineapple
     8  apple
     9  pen
    10
root@nextcloud1:~#
root@nextcloud1:~# sed '5s/^/#/' test
foo
;bar
;memory_limit

#nyaa
pen
#pineapple
apple
pen

root@nextcloud1:~#
root@nextcloud1:~# sed '5s/^/#/' test -i
root@nextcloud1:~#
root@nextcloud1:~# cat -n test
     1  foo
     2  ;bar
     3  ;memory_limit
     4
     5  #nyaa
     6  pen
     7  #pineapple
     8  apple
     9  pen
    10
root@nextcloud1:~#

複数行削除

6-10 行目を削除

root@nextcloud1:~# cat -n test
     1  foo
     2  ;bar
     3  ;memory_limit
     4
     5  #nyaa
     6  pen
     7  #pineapple
     8  apple
     9  pen
    10
root@nextcloud1:~#
root@nextcloud1:~# sed '6,10d' test
foo
;bar
;memory_limit

#nyaa
root@nextcloud1:~# sed '6,10d' test -i
root@nextcloud1:~#
root@nextcloud1:~# cat -n test
     1  foo
     2  ;bar
     3  ;memory_limit
     4
     5  #nyaa
root@nextcloud1:~#

行末に追記

3 行目の行末に =512M を追記

root@nextcloud1:~# cat -n test
     1  foo
     2  ;bar
     3  ;memory_limit
     4
     5  #nyaa
root@nextcloud1:~#
root@nextcloud1:~# sed '3s/$/=512M/' test
foo
;bar
;memory_limit=512M

#nyaa
root@nextcloud1:~# sed '3s/$/=512M/' test -i
root@nextcloud1:~#
root@nextcloud1:~# cat -n test
     1  foo
     2  ;bar
     3  ;memory_limit=512M
     4
     5  #nyaa
root@nextcloud1:~#

1行目に挿入

1行目に適当なシェバンを挿入

root@nextcloud1:~# cat -n test
     1  foo
     2  ;bar
     3  ;memory_limit=512M
     4
     5  #nyaa
root@nextcloud1:~#
root@nextcloud1:~# sed '1i#!/bin/bash' test
#!/bin/bash
foo
;bar
;memory_limit=512M

#nyaa
root@nextcloud1:~# sed '1i#!/bin/bash' test -i
root@nextcloud1:~# cat -n test
     1  #!/bin/bash
     2  foo
     3  ;bar
     4  ;memory_limit=512M
     5
     6  #nyaa
root@nextcloud1:~#

最終行の次の行に追記

最終行の次の行に追記
再修行は $ で表現できる

root@nextcloud1:~# cat -n test
     1  #!/bin/bash
     2  foo
     3  ;bar
     4  ;memory_limit=512M
     5
     6  #nyaa
root@nextcloud1:~#
root@nextcloud1:~# sed '$aEOF' test
#!/bin/bash
foo
;bar
;memory_limit=512M

#nyaa
EOF
root@nextcloud1:~# sed '$aEOF' test -i
root@nextcloud1:~#
root@nextcloud1:~# cat -n test
     1  #!/bin/bash
     2  foo
     3  ;bar
     4  ;memory_limit=512M
     5
     6  #nyaa
     7  EOF
root@nextcloud1:~#

最終行の次の行に改行付きで追記

バックスラッシュ \ は バックスラッシュでエスケープすることで利用できる

root@nextcloud1:~# cat -n test
     1  #!/bin/bash
     2  foo
     3  ;bar
     4  ;memory_limit=512M
     5
     6  #nyaa
root@nextcloud1:~#
root@nextcloud1:~# sed '$a\\nEOF' test
#!/bin/bash
foo
;bar
;memory_limit=512M

#nyaa

EOF
root@nextcloud1:~# sed '$a\\nEOF' test -i
root@nextcloud1:~#
root@nextcloud1:~# cat -n test
     1  #!/bin/bash
     2  foo
     3  ;bar
     4  ;memory_limit=512M
     5
     6  #nyaa
     7
     8  EOF
root@nextcloud1:~#

指定行を全部書き換える

6行目を書き換える

root@nextcloud1:~# cat -n test
     1  #!/bin/bash
     2  foo
     3  ;bar
     4  ;memory_limit=512M
     5
     6  #nyaa
     7
     8  EOF
root@nextcloud1:~#
root@nextcloud1:~# sed '6cfunction nyaa() {}' test
#!/bin/bash
foo
;bar
;memory_limit=512M

function nyaa() {}

EOF
root@nextcloud1:~# sed '6cfunction nyaa() {}' test -i
root@nextcloud1:~#
root@nextcloud1:~# cat -n test
     1  #!/bin/bash
     2  foo
     3  ;bar
     4  ;memory_limit=512M
     5
     6  function nyaa() {}
     7
     8  EOF
root@nextcloud1:~#

指定行を表示

-n オプションを指定して、 数字p でその数字の行が表示される
pprintp だろうと思う

# 元ファイル
$ cat -n test
     1  #!/bin/bash
     2  foo
     3  ;bar
     4  ;memory_limit=512M
     5
     6  function nyaa() {}
     7
     8  EOF
$

# 3 行目を表示
$ sed -n '3p' test
;bar
$

# 3 から 5 行目を表示
$ sed -n '3,5p' test
;bar
;memory_limit=512M

$

# 4行目、6行目を表示
$ sed -n -e '4p' -e '6p' test
;memory_limit=512M
function nyaa() {}
$

# x行から y 行ごとに表示
$ cat -n test | sed -n '2~1p'
     2  foo
     3  ;bar
     4  ;memory_limit=512M
     5
     6  function nyaa() {}
     7
     8  EOF
$
$ cat -n test | sed -n '2~2p'
     2  foo
     4  ;memory_limit=512M
     6  function nyaa() {}
     8  EOF
$
$ cat -n test | sed -n '2~3p'
     2  foo
     5
     8  EOF
$

# x 行目から +y 行表示
$ cat -n test | sed -n '2,+1p'
     2  foo
     3  ;bar
$
$ cat -n test | sed -n '2,+2p'
     2  foo
     3  ;bar
     4  ;memory_limit=512M
$

# 最終行を表示する
$ cat -n test | sed -n '$p'
     8  EOF
$

特定の文字列の行を表示する

$ cat -n test | sed -n '/func/p'
     6  function nyaa() {}
$

sed の append / insert などで、シェル変数を使う

$ val="apple"

# 最終行に append する
$ cat test
#!/bin/bash
foo
;bar
;memory_limit=512M

function nyaa() {}

EOF
$ sed "\$a ${val}" test
#!/bin/bash
foo
;bar
;memory_limit=512M

function nyaa() {}

EOF
apple
$

# 最後の行の1行上に insert する
$ sed "\$i ${val}" test
#!/bin/bash
foo
;bar
;memory_limit=512M

function nyaa() {}

apple
EOF
$

最終行の行数や文字列が分かっているなら、このようなエスケープをする必要はない

感想

sed ってすごい柔軟なコマンドなんだなと思った
shell 芸人達はもっと使いこなしているんだと思うと、ちょっと恐ろしくなったが、面白そうと思った


2024-04-16 追記

奇数行のみ表示

sed -n 'p;n' FILENAME
# p コマンド -> 現在の行を表示 (おそらく print の p )
# n コマンド -> 次の行に移動する (おそらく next の n )
# p;n コマンド -> 現在の行を出力して次の行に移動する
# -n オプション -> 明示的に `p コマンド` で指定された行以外は出力しない

sample

$ cat -n foooo
     1  aaa
     2  bbbbb
     3  cccc
     4  dddd
     5  eeeeeee
     6  ffff
     7
$
$ cat -n foooo | sed -n 'p;n'
     1  aaa
     3  cccc
     5  eeeeeee
     7
$

偶数行のみ表示

sed -n 'n;p' FILENAME

sample

$ cat -n foooo
     1  aaa
     2  bbbbb
     3  cccc
     4  dddd
     5  eeeeeee
     6  ffff
     7
$
$ cat -n foooo | sed -n 'n;p'
     2  bbbbb
     4  dddd
     6  ffff
$