# Tham Khảo Nhanh sed

*Chỉnh sửa luồng, thay thế, địa chỉ, hold space và biến đổi tại chỗ*

> Source: GNU sed Manual (gnu.org/software/sed) · MIT

## Cơ Bản

### Chạy sed

```
sed 's/old/new/' file.txt          # substitute first match per line
sed 's/old/new/g' file.txt         # substitute all matches per line
sed -n '5p' file.txt               # print only line 5
sed '3d' file.txt                  # delete line 3
echo "hello" | sed 's/hello/hi/'   # pipe input
```

### Cờ Dòng Lệnh

| Command | Description |
|---------|-------------|
| `-n` | Tắt in tự động; chỉ in với `p` |
| `-e 'cmd'` | Thực thi lệnh sed (kết hợp nhiều với `-e`) |
| `-f script.sed` | Đọc lệnh từ file |
| `-i[suffix]` | Sửa file tại chỗ (hậu tố backup tùy chọn) |
| `-E / -r` | Dùng biểu thức chính quy mở rộng |

## Thay Thế

### Cú Pháp Thay Thế

```
sed 's/foo/bar/' f                 # first occurrence per line
sed 's/foo/bar/g' f                # all occurrences
sed 's/foo/bar/3' f                # 3rd occurrence only
sed 's/foo/bar/gi' f               # all, case-insensitive
sed 's|/usr/bin|/opt/bin|g' f      # alternate delimiter
```

### Cờ Thay Thế

| Command | Description |
|---------|-------------|
| `g` | Thay thế tất cả lần xuất hiện trong dòng |
| `N (số)` | Chỉ thay thế lần xuất hiện thứ N |
| `p` | In dòng nếu thay thế được thực hiện |
| `w file` | Ghi các dòng đã thay thế vào file |
| `i / I` | Khớp không phân biệt hoa/thường (GNU) |

## Địa Chỉ

### Ví Dụ Địa Chỉ

```
sed '3s/a/b/' f                    # only on line 3
sed '2,5s/a/b/' f                  # lines 2 through 5
sed '/^#/d' f                      # delete lines starting with #
sed '/start/,/end/d' f             # delete range between patterns
sed '1~2d' f                       # delete odd-numbered lines (GNU)
```

### Kiểu Địa Chỉ

| Command | Description |
|---------|-------------|
| `N` | Số dòng N |
| `$` | Dòng cuối |
| `N,M` | Dải dòng từ N đến M |
| `/regex/` | Các dòng khớp regex |
| `/regex1/,/regex2/` | Dải từ khớp đầu đến khớp thứ hai |
| `N~step` | Bắt đầu từ N, mỗi step dòng (GNU) |
| `addr!` | Phủ định — áp dụng cho dòng không khớp |

## Xóa & In

### Lệnh Xóa & In

```
sed '5d' f                         # delete line 5
sed '/^$/d' f                      # delete blank lines
sed -n '10,20p' f                  # print lines 10–20
sed -n '/error/p' f                # print lines matching pattern
sed '/debug/!d' f                  # keep only matching lines
```

### Tham Chiếu Lệnh

| Command | Description |
|---------|-------------|
| `d` | Xóa pattern space, bắt đầu chu kỳ tiếp theo |
| `D` | Xóa đến ký tự xuống dòng đầu trong pattern space |
| `p` | In pattern space |
| `P` | In đến ký tự xuống dòng đầu trong pattern space |
| `q` | Thoát sau khi in pattern space hiện tại |
| `Q` | Thoát không in (GNU) |

## Chèn & Thêm

### Chèn, Thêm, Thay Thế

```
sed '3i\inserted line' f           # insert before line 3
sed '3a\appended line' f           # append after line 3
sed '3c\replaced line' f           # replace line 3
sed '/marker/a\new line' f         # append after pattern match
```

### Lệnh

| Command | Description |
|---------|-------------|
| `i\text` | Chèn text trước dòng hiện tại |
| `a\text` | Thêm text sau dòng hiện tại |
| `c\text` | Thay thế dòng hiện tại bằng text |
| `r file` | Đọc và thêm nội dung file |
| `R file` | Đọc và thêm một dòng từ file (GNU) |
| `w file` | Ghi pattern space vào file |

## Hold Space

### Lệnh Hold Space

| Command | Description |
|---------|-------------|
| `h` | Sao chép pattern space vào hold space |
| `H` | Thêm pattern space vào hold space |
| `g` | Sao chép hold space vào pattern space |
| `G` | Thêm hold space vào pattern space |
| `x` | Hoán đổi pattern và hold space |

### Ví Dụ Hold Space

```
sed -n '1!G;h;$p' f               # reverse lines (tac)
sed '/^$/{ x; s/\n//; x; }' f     # collapse hold on blank
sed -n 'H;${x;s/\n/ /g;p;}' f     # join all lines with space
```

## Nhiều Lệnh

### Nối Chuỗi Lệnh

```
sed -e 's/foo/bar/g' -e 's/baz/qux/g' f
sed 's/foo/bar/g; s/baz/qux/g' f
sed '/header/{ s/old/new/; s/foo/bar/; }' f
sed -f commands.sed input.txt
```

### Nhóm & Phân Nhánh

| Command | Description |
|---------|-------------|
| `{ cmd1; cmd2; }` | Nhóm lệnh cho cùng địa chỉ |
| `:label` | Định nghĩa nhãn phân nhánh |
| `b label` | Phân nhánh (nhảy) đến nhãn |
| `t label` | Phân nhánh nếu `s///` cuối thành công |
| `T label` | Phân nhánh nếu `s///` cuối thất bại (GNU) |

## Sửa Tại Chỗ

### Ví Dụ Sửa Tại Chỗ

```
sed -i 's/old/new/g' file.txt            # edit in place (GNU)
sed -i.bak 's/old/new/g' file.txt        # backup as file.txt.bak
sed -i '' 's/old/new/g' file.txt         # macOS in-place (no backup)
sed -i '/^#/d' config.txt                # remove comments in place
```

### Ghi Chú Nền Tảng

| Command | Description |
|---------|-------------|
| `GNU sed -i` | Hậu tố tùy chọn; `-i` một mình sửa không backup |
| `BSD/macOS sed -i` | Cần đối số hậu tố; dùng `-i ''` để không backup |
| `-i.bak` | Tạo file backup với phần mở rộng `.bak` |
| `Nhiều file` | `sed -i 's/a/b/g' *.txt` sửa tất cả file khớp |

## Regex

### Regex trong sed

| Command | Description |
|---------|-------------|
| `.` | Bất kỳ ký tự đơn nào |
| `*` | Không hoặc nhiều ký tự trước |
| `\+` | Một hoặc nhiều (BRE) — `+` trong ERE |
| `\?` | Không hoặc một (BRE) — `?` trong ERE |
| `^` | Đầu dòng |
| `$` | Cuối dòng |
| `[abc]` | Lớp ký tự |
| `\( \)` | Nhóm bắt (BRE) — `()` trong ERE |
| `\1, \2` | Tham chiếu ngược đến nhóm bắt |
| `&` | Toàn bộ chuỗi khớp (trong thay thế) |

### Ví Dụ Regex

```
sed 's/[0-9]\+/NUM/g' f               # replace numbers
sed -E 's/(foo)(bar)/\2\1/g' f         # swap groups (ERE)
sed 's/.*/(&)/' f                      # wrap line in parens
sed 's/[ \t]*$//' f                    # strip trailing whitespace
```

## Mẫu Phổ Biến

### One-Liner

```
sed -n '1p' f                          # first line (head -1)
sed '$!d' f                            # last line (tail -1)
sed '/^$/d' f                          # remove blank lines
sed 's/^[ \t]*//' f                    # strip leading whitespace
sed '=' f | sed 'N;s/\n/\t/' f         # number lines
```

### Công Thức

| Command | Description |
|---------|-------------|
| `Giãn đôi dòng` | `sed G` — thêm dòng trắng sau mỗi dòng |
| `Xóa thẻ HTML` | `sed 's/<[^>]*>//g'` |
| `Trích xuất email` | `sed -nE 's/.*([a-z]+@[a-z.]+).*/\1/p'` |
| `Thêm comment dòng` | `sed 's/^/# /'` — thêm `# ` vào đầu mỗi dòng |
| `Xóa dòng trắng cuối file` | `sed -e :a -e '/^\n*$/{$d;N;ba' -e '}'` |
| `Thay thế dòng thứ N` | `sed 'Nc\new text'` — thay thế dòng N |
