Awk / Sed

sed Basic Substitution

sed 's/old/new/' file.txt              # replace first occurrence per line
sed 's/old/new/g' file.txt             # replace all occurrences
sed 's/old/new/2' file.txt             # replace 2nd occurrence per line
sed -i 's/old/new/g' file.txt          # in-place edit
echo "hello123" | sed 's/[0-9]//g'     # remove all digits

sed Delete & Insert

sed '/pattern/d' file.txt              # delete matching lines
sed '3d' file.txt                      # delete line 3
sed '1,5d' file.txt                    # delete lines 1-5
sed '/^$/d' file.txt                   # delete blank lines
sed '2i\inserted line' file.txt        # insert before line 2
sed '2a\appended line' file.txt        # append after line 2
sed '2c\replaced line' file.txt        # replace line 2

sed Multi-line

sed 'N;s/\n/ /' file.txt              # join pairs of lines
sed ':a;N;$!ba;s/\n/ /g' file.txt     # join all lines into one
sed '/start/,/end/d' file.txt         # delete range between patterns
sed '/start/,/end/s/old/new/g' file.txt

sed In-place Edit

sed -i.bak 's/old/new/g' file.txt     # in-place with backup
sed -i '' 's/old/new/g' file.txt      # macOS in-place (no backup)
sed -i -e 's/old/new/g' file.txt

sed Addresses & Ranges

sed -n '5p' file.txt                   # print only line 5
sed -n '5,10p' file.txt                # print lines 5-10
sed -n '$p' file.txt                   # print last line
sed -n '/pattern/p' file.txt           # print matching lines
sed -n '/start/,/end/p' file.txt       # print range between patterns
sed '1~2d' file.txt                    # delete every other line starting from 1

awk Basic Usage

awk '{print}' file.txt                 # print all lines
awk '{print $1}' file.txt              # print first field
awk '{print $1, $3}' file.txt          # print field 1 and 3
awk '/pattern/{print}' file.txt        # print matching lines
awk '{print NR, $0}' file.txt          # print with line numbers

awk Fields & Separators

awk -F',' '{print $1, $2}' file.csv   # comma separator
awk -F'\t' '{print $1}' file.tsv      # tab separator
awk -F':' '{print $1}' /etc/passwd
awk 'BEGIN{FS=","; OFS="|"} {print $1, $2}' file.csv
awk '{print NF}' file.txt              # number of fields per line
awk '{print $NF}' file.txt             # last field
awk '{print $(NF-1)}' file.txt         # second to last field

awk Patterns & Conditions

awk '$3 > 100' file.txt                # field 3 greater than 100
awk '$1 == "root"' /etc/passwd
awk '/start/,/end/' file.txt           # range pattern
awk 'NR > 1' file.txt                  # skip header line
awk 'NR >= 5 && NR <= 10' file.txt     # lines 5 to 10
awk '$3 ~ /^[0-9]+$/' file.txt         # regex match field 3
awk '$3 !~ /pattern/' file.txt         # regex NOT match

awk Variables

awk '{sum += $1} END {print sum}' file.txt
awk '{sum += $1; count++} END {print sum/count}' file.txt
awk 'BEGIN {pi=3.14159; print pi}'
awk '{arr[NR] = $0} END {for(i=NR;i>0;i--) print arr[i]}' file.txt
awk '{len = length($0); if(len > max) max = len} END {print max}' file.txt

awk Control Flow

awk '{if ($3 > 50) print $1, "high"; else print $1, "low"}' file.txt
awk '{
  for (i = 1; i <= NF; i++) {
    if ($i > 100) print $i
  }
}' file.txt
awk '{
  i = 1
  while (i <= NF) {
    print $i; i++
  }
}' file.txt

awk Arrays

awk '{count[$1]++} END {for(k in count) print k, count[k]}' file.txt
awk '{sum[$1] += $2} END {for(k in sum) print k, sum[k]}' file.txt
awk '!seen[$1]++' file.txt             # deduplicate by field 1
awk '{a[$1] = a[$1] ? a[$1]","$2 : $2} END {for(k in a) print k, a[k]}' file.txt

awk Functions

awk '{print length($0)}' file.txt      # string length
awk '{print substr($0, 1, 10)}' file.txt
awk '{print toupper($1)}' file.txt
awk '{print tolower($1)}' file.txt
awk '{print index($0, "pattern")}' file.txt
awk '{print split($0, arr, ",")}' file.txt
awk '{gsub(/old/, "new"); print}' file.txt

awk One-liners

awk 'END{print NR}' file.txt           # count lines
awk '{s+=$1} END{print s}' file.txt    # sum column 1
awk 'NR%2==0' file.txt                 # print even lines
awk '{gsub(/\r/,""); print}' file.txt  # remove carriage returns
awk '{$1=$1; print}' file.txt          # normalize whitespace
awk '{print length, $0}' file.txt | sort -rn | head -5  # longest lines

Practical Examples

# Extract usernames from passwd
awk -F':' '{print $1}' /etc/passwd

# Sum file sizes in directory listing
ls -l | awk '{sum += $5} END {print sum " bytes"}'

# CSV column extraction with header skip
awk -F',' 'NR > 1 {print $2, $5}' data.csv

# Find top 10 IPs in access log
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10

# Swap two columns
awk '{print $2, $1, $3}' file.txt

# Count occurrences of unique values in column 1
awk -F',' '{count[$1]++} END {for(k in count) print k, count[k]}' data.csv

# Remove HTML tags
sed 's/<[^>]*>//g' file.html

# Add line numbers to file
sed '=' file.txt | sed 'N;s/\n/\t/'

sed 基础替换

sed 's/old/new/' file.txt              # 每行替换第一个匹配
sed 's/old/new/g' file.txt             # 替换所有匹配
sed 's/old/new/2' file.txt             # 每行替换第 2 个匹配
sed -i 's/old/new/g' file.txt          # 就地编辑
echo "hello123" | sed 's/[0-9]//g'     # 删除所有数字

sed 删除与插入

sed '/pattern/d' file.txt              # 删除匹配行
sed '3d' file.txt                      # 删除第 3 行
sed '1,5d' file.txt                    # 删除第 1-5 行
sed '/^$/d' file.txt                   # 删除空行
sed '2i\inserted line' file.txt        # 在第 2 行前插入
sed '2a\appended line' file.txt        # 在第 2 行后追加
sed '2c\replaced line' file.txt        # 替换第 2 行

sed 多行操作

sed 'N;s/\n/ /' file.txt              # 合并相邻两行
sed ':a;N;$!ba;s/\n/ /g' file.txt     # 合并所有行为一行
sed '/start/,/end/d' file.txt         # 删除两个模式之间的内容
sed '/start/,/end/s/old/new/g' file.txt

sed 就地编辑

sed -i.bak 's/old/new/g' file.txt     # 就地编辑并备份
sed -i '' 's/old/new/g' file.txt      # macOS 就地编辑 (无备份)
sed -i -e 's/old/new/g' file.txt

sed 地址与范围

sed -n '5p' file.txt                   # 仅打印第 5 行
sed -n '5,10p' file.txt                # 打印第 5-10 行
sed -n '$p' file.txt                   # 打印最后一行
sed -n '/pattern/p' file.txt           # 打印匹配行
sed -n '/start/,/end/p' file.txt       # 打印两个模式之间的行
sed '1~2d' file.txt                    # 从第 1 行起隔行删除

awk 基础用法

awk '{print}' file.txt                 # 打印所有行
awk '{print $1}' file.txt              # 打印第一个字段
awk '{print $1, $3}' file.txt          # 打印第 1 和第 3 个字段
awk '/pattern/{print}' file.txt        # 打印匹配行
awk '{print NR, $0}' file.txt          # 带行号打印

awk 字段与分隔符

awk -F',' '{print $1, $2}' file.csv   # 逗号分隔
awk -F'\t' '{print $1}' file.tsv      # 制表符分隔
awk -F':' '{print $1}' /etc/passwd
awk 'BEGIN{FS=","; OFS="|"} {print $1, $2}' file.csv
awk '{print NF}' file.txt              # 每行字段数
awk '{print $NF}' file.txt             # 最后一个字段
awk '{print $(NF-1)}' file.txt         # 倒数第二个字段

awk 模式与条件

awk '$3 > 100' file.txt                # 第 3 列大于 100
awk '$1 == "root"' /etc/passwd
awk '/start/,/end/' file.txt           # 范围模式
awk 'NR > 1' file.txt                  # 跳过表头
awk 'NR >= 5 && NR <= 10' file.txt     # 第 5 到 10 行
awk '$3 ~ /^[0-9]+$/' file.txt         # 正则匹配第 3 列
awk '$3 !~ /pattern/' file.txt         # 正则不匹配

awk 变量

awk '{sum += $1} END {print sum}' file.txt
awk '{sum += $1; count++} END {print sum/count}' file.txt
awk 'BEGIN {pi=3.14159; print pi}'
awk '{arr[NR] = $0} END {for(i=NR;i>0;i--) print arr[i]}' file.txt
awk '{len = length($0); if(len > max) max = len} END {print max}' file.txt

awk 控制流

awk '{if ($3 > 50) print $1, "high"; else print $1, "low"}' file.txt
awk '{
  for (i = 1; i <= NF; i++) {
    if ($i > 100) print $i
  }
}' file.txt
awk '{
  i = 1
  while (i <= NF) {
    print $i; i++
  }
}' file.txt

awk 数组

awk '{count[$1]++} END {for(k in count) print k, count[k]}' file.txt
awk '{sum[$1] += $2} END {for(k in sum) print k, sum[k]}' file.txt
awk '!seen[$1]++' file.txt             # 按第 1 列去重
awk '{a[$1] = a[$1] ? a[$1]","$2 : $2} END {for(k in a) print k, a[k]}' file.txt

awk 函数

awk '{print length($0)}' file.txt      # 字符串长度
awk '{print substr($0, 1, 10)}' file.txt
awk '{print toupper($1)}' file.txt
awk '{print tolower($1)}' file.txt
awk '{print index($0, "pattern")}' file.txt
awk '{print split($0, arr, ",")}' file.txt
awk '{gsub(/old/, "new"); print}' file.txt

awk 单行命令

awk 'END{print NR}' file.txt           # 统计行数
awk '{s+=$1} END{print s}' file.txt    # 求和第 1 列
awk 'NR%2==0' file.txt                 # 打印偶数行
awk '{gsub(/\r/,""); print}' file.txt  # 去除回车符
awk '{$1=$1; print}' file.txt          # 规范化空白
awk '{print length, $0}' file.txt | sort -rn | head -5  # 最长的行

实用示例

# 从 passwd 提取用户名
awk -F':' '{print $1}' /etc/passwd

# 统计目录中文件总大小
ls -l | awk '{sum += $5} END {print sum " bytes"}'

# CSV 列提取 (跳过表头)
awk -F',' 'NR > 1 {print $2, $5}' data.csv

# 统计访问日志中 Top 10 IP
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10

# 交换两列
awk '{print $2, $1, $3}' file.txt

# 统计第 1 列唯一值出现次数
awk -F',' '{count[$1]++} END {for(k in count) print k, count[k]}' data.csv

# 去除 HTML 标签
sed 's/<[^>]*>//g' file.html

# 给文件加行号
sed '=' file.txt | sed 'N;s/\n/\t/'