empty pattern space

이 명령은 현재 pattern space 를 empty 로 만듭니다. 그러므로 결과적으로는 s/.*// 명령과 같지만 좀 더 효율적으로 실행이 되고 . 로 매칭이 되지 않아 삭제가 안되는 invalid multibyte sequences 경우도 삭제를 할 수가 있습니다.

1. pattern space 가 삭제된 후 d 명령과는 다르게 현재 명령 사이클 위치에서 실행을 계속합니다.

transliterate

y / source-chars / dest-chars /

source-chars 에 있는 문자들을 위치상으로 매칭 되는 dest-chars 문자로 바꿉니다.
그러니까 source-chars 와 dest-chars 는 문자 수가 같아야 합니다.

$ echo "A00 B11 C22 D33 E44" | sed 'y/ABCDEFGHIJ/0123456789/'
000 111 222 333 444

$ echo -e "space tab\tnew\nline" | sed 'N; y# \t\n#XYZ#'
spaceXtabYnewZline

# 'y' 명령에서는 regex 메타문자들을 escape 하지 않아도 된다,
$ echo '^|$+' | sed 'y/$+|^/ABCD/'
DCAB

한가지 참고할 사항은 y 명령이 위치한 행은 뒤에 comment 를 붙이면 오류가 발생합니다.

line number

현재 라인 넘버를 출력합니다.

$ ls -l /bin | sed = 
1
total 16396
2
-rwxr-xr-x 1 root root 1113504 2018-04-05 03:30 bash*
3
-rwxr-xr-x 1 root root  748968 2018-04-17 19:46 brltty*
4
-rwxr-xr-x 1 root root  716464 2018-03-13 08:04 btrfs*
. . .
. . .
178
-rwxr-xr-x 1 root root    2037 2017-04-28 12:50 zless*
179
-rwxr-xr-x 1 root root    1910 2017-04-28 12:50 zmore*
180
-rwxr-xr-x 1 root root    5047 2017-04-28 12:50 znew*
-----------------------------------------------------

$ ls -l /bin | sed 4=  
total 16396
-rwxr-xr-x 1 root root 1113504 2018-04-05 03:30 bash*
-rwxr-xr-x 1 root root  748968 2018-04-17 19:46 brltty*
4
-rwxr-xr-x 1 root root  716464 2018-03-13 08:04 btrfs*
lrwxrwxrwx 1 root root       5 2018-03-13 08:04 btrfsck -> btrfs*
-rwxr-xr-x 1 root root  375952 2018-03-13 08:04 btrfs-debug-tree*
-rwxr-xr-x 1 root root  371856 2018-03-13 08:04 btrfs-find-root*
. . .
. . .

다음은 total number of lines 를 구하는 예입니다.

$ ls -l /usr/bin/ | wc -l
2954

$ ls -l /usr/bin/ | sed -n $= 
2954

$ ls -l /usr/bin/ | awk 'END {print NR}'
2954

예제 )

다음과 같은 형식의 데이터 파일이 있을 경우 dev= 값과 port= 값이 모두 존재하는 경우만 dev=ke_1p,port=8001 형식으로 출력하는 것입니다.

$ cat data
[p1]
seq=1
pr=13
pt=15
dev=ke_1p          # dev 값
ad=/asd/asd
port=8001          # port 값

[p2]
seq=2
pr=13
pt=15
dev=ke_2p
ad=/asd/qwe        # port 값이 없음

[p3]
seq=3
pr=13
pt=15              # dev 값이 없음
ad=/asd/qwe
port=8003

[p4]
seq=4
pr=13
pt=15
dev=ke_4p
ad=/asd/qwe
port=8004
------------------

$ sed -n '/^[[:blank:]]*$/{h;b}; {  # 공백 라인일 경우 hold 하면 hold space 도 clear 됩니다.
    /dev=/{h;b};            # dev= 라인일 경우 hold space 에 저장하고 식의 끝으로 분기합니다. 
    /port=/{ H;g;           # port= 라인일 경우 hold space 에 append 한후 다시 pattern space 로 가져와
        /dev=/{ s/\n/,/p }  # dev= 라인이 있는지 체크후 newline 을 ',' 로 변경해 출력합니다.
    }
}' data
dev=ke_1p,port=8001
dev=ke_4p,port=8004

Quiz

다음과 같이 주어진 스트링에서 (...) 괄호를 삭제하는 것입니다. 그런데 괄호안에 cat 또는 lion 이 있을경우는 삭제하지 않습니다.

$ echo 'AAA (foo) (lion 80) BBB (bar 11) (cat 92) CCC' |
sed -E -e 's/\(([^)]*(cat|lion)[^)]*)\)/\a\1\v/g' \
       -e 's/\([^)]*\) //g' \
       -e 'y/\a\v/\(\)/'

AAA (lion 80) BBB (cat 92) CCC

-------------------------------------------------------

1. 먼저 's/\(([^)]*(cat|lion)[^)]*)\)/\a\1\v/g' 식에 의해 괄호안에 
   cat 또는 lion 이 있을경우 '(lion 80)' --> '\alion 80\v' 형태로 변경합니다.

2. 두번째 's/\([^)]*\) //g' 식에 의해 나머지 괄호는 모두 삭제됩니다.

3. 마지막으로 'y/\a\v/\(\)/' 식으로 '\a' --> '(' , '\v' --> ')' 로 변경합니다.