Linux 文本处理工具

Linux 系统自带了许多强大的文本处理工具,这些工具小巧高效,通常通过管道(|)组合使用,能完成复杂的文本处理任务。以下是最常用的文本处理工具分类及功能介绍:

一、文本查看工具

  1. cat

    • 功能:连接并打印文件内容(concatenate 的缩写)。

    • 常用场景:查看小型文件、创建文件、合并文件。

    • 示例:

      cat file.txt          # 查看文件内容
      cat file1.txt file2.txt > merged.txt  # 合并文件
  2. more/less

    • 功能:分页查看大型文件(支持翻页、搜索)。

    • 区别:less 功能更强大(支持前后翻页、按行滚动),more 仅支持向前翻页。

    • 示例:

      less large_log.txt    # 分页查看,按 q 退出,/keyword 搜索
  3. head/tail

    • 功能:查看文件的开头 / 结尾部分。

    • 常用选项:-n 指定行数(默认 10 行),tail -f 实时跟踪文件更新(适合日志)。

    • 示例:

      head -5 file.txt      # 查看前5行
      tail -f /var/log/syslog  # 实时监控日志

二、文本搜索工具

  1. grep

    • 功能:按模式(正则表达式)搜索文本,支持递归搜索目录。

    • 核心选项:

      • -i:忽略大小写
      • -r:递归搜索目录
      • -n:显示匹配行的行号
      • -v:反向匹配(输出不匹配的行)
    • 示例:

      grep "error" log.txt  # 搜索含 "error" 的行
      grep -rni "password" /etc/  # 递归搜索/etc下含 "password" 的文件(忽略大小写)
  2. egrep/fgrep

    • egrep:等价于 grep -E,支持扩展正则表达式(如 | 表示 “或”)。
    • fgrep:等价于 grep -F,仅匹配固定字符串(不解析正则,速度更快)。

三、文本处理与转换工具

  1. awk

    • 功能:按行处理文本,按字段分割内容,支持条件判断、统计、格式化输出。

    • 示例:提取 CSV 文件的第 2 列并过滤数值大于 100 的行:

      awk -F ',' '$2 > 100 {print $1, $2}' data.csv
  2. sed

    • 功能:流式文本编辑器,擅长文本替换、删除、插入等操作(stream editor)。
    • 核心用法:sed [选项] '命令' 文件
    • 常用命令:
      • s/old/new/:替换匹配的字符串(默认只替换每行第一个)
      • d:删除行
      • i/a:在指定行前 / 后插入内容
    • 示例:
        sed 's/error/ERROR/g' log.txt  # 全局替换 "error" 为 "ERROR"
        sed '/^#/d' config.txt         # 删除所有注释行(以 # 开头的行)
        ```
 
3. **cut**
    
    - 功能:按列(字段)提取文本内容。
    - 常用选项:`-d` 指定分隔符,`-f` 指定字段索引。
    - 示例:提取 `/etc/passwd` 中用户的用户名和 Shell(冒号分隔):
 
        ```bash
        cut -d ':' -f 1,7 /etc/passwd
        ```
 
4. **paste**
    
    - 功能:按列合并多个文件(与 `cut` 相反)。
    - 示例:将两个文件按列拼接,用逗号分隔:
 
        ```bash
        paste -d ',' file1.txt file2.txt
        ```
 
### 四、文本排序与去重工具
 
1. **sort**
    
    - 功能:对文本行排序,支持按字段、数值 / 字符串、升序 / 降序排序。
    - 常用选项:
        - `-n`:按数值排序(默认按字符串)
        - `-k`:指定排序的字段(如 `-k3` 按第 3 字段)
        - `-r`:降序排序
        - `-t`:指定字段分隔符
    - 示例:按第 2 字段(数值)降序排序:
 
        ```bash
        sort -t ' ' -k2 -nr data.txt
        ```
 
2. **uniq**
    
    - 功能:去除连续重复的行(常与 `sort` 配合使用以去重所有重复行)。
    - 常用选项:
        - `-c`:统计每行出现的次数
        - `-u`:只显示唯一的行(不重复的行)
    - 示例:统计文件中各单词出现的次数(需先排序):
        
 
        ```bash
        cat words.txt | sort | uniq -c
        ```
 
### 五、其他实用工具
 
1. **wc**
    
    - 功能:统计文本的行数、单词数、字节数(`word count`)。
    - 示例:
 
        ```bash
        wc -l file.txt  # 统计行数
        wc -w file.txt  # 统计单词数
        ```
 
2. **tr**
    
    - 功能:字符转换或删除(`translate`),支持字符集替换。
    - 示例:
        
        bash
        
        ```bash
        tr 'a-z' 'A-Z' < file.txt  # 小写转大写
        tr -d ' ' < file.txt       # 删除所有空格
        ```
 
2. **join**
    
    - 功能:按共同字段连接两个文件(类似 SQL 的 JOIN 操作)。
    - 示例:按第 1 字段连接两个文件:
        
 
        ```bash
        join -t ',' file1.csv file2.csv
        ```
 
 
### 六、工具组合示例
 
Linux 文本工具的强大之处在于通过管道(`|`)组合使用,例如:
 
```bash
# 统计日志中不同 IP 出现的次数(按次数降序)
grep "Failed login" /var/log/auth.log | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | sort | uniq -c | sort -nr

以上工具是 Linux 文本处理的基石,熟练掌握后能极大提升处理日志、配置文件、数据清洗等任务的效率。

管道

Shell 中的管道(|)本质上就是进程间通信(IPC)的一种实现方式,它基于 Linux 内核提供的匿名管道(anonymous pipe) 机制,专门用于连接两个或多个进程,实现它们之间的单向数据传递。

具体来说

当在 Shell 中执行 cmd1 | cmd2 时,Shell 会完成以下操作:

  1. 创建一个匿名管道(由内核维护的内存缓冲区)。
  2. 启动两个独立的进程:cmd1(左侧命令)和 cmd2(右侧命令)。
  3. 将 cmd1 的标准输出(stdout) 重定向到管道的 “写端”。
  4. 将 cmd2 的标准输入(stdin) 重定向到管道的 “读端”。
  5. 这样,cmd1 输出的数据会通过管道流向 cmd2,实现两个进程间的通信。

为什么说它是进程间通信的管道?

  • 通信主体是进程| 连接的是独立的进程(如 grep 和 wc 是两个不同进程),而非线程或其他单元。
  • 依赖内核管道机制:底层完全依赖 Linux 的 pipe() 系统调用创建的管道,具备管道的核心特性(FIFO 字节流、单向通信、阻塞机制等)。
  • 典型的 IPC 场景:目的是让不同进程共享数据(前一个进程的输出作为后一个进程的输入),符合进程间通信的定义。

补充说明

Shell 管道是匿名管道的典型应用,它与 Linux 中另一种管道(命名管道,FIFO)的区别在于:

  • 匿名管道(Shell 管道):由 Shell 临时创建,仅在关联进程的生命周期内存在,进程退出后自动销毁,没有文件系统路径。
  • 命名管道(FIFO):通过 mkfifo 命令创建,以文件形式存在于文件系统中,可用于任意进程间通信(不限于 Shell 命令),生命周期与系统重启无关。

但无论匿名还是命名,它们的核心机制一致,都是进程间通过内核缓冲区传递数据的 IPC 方式。因此,Shell 的管道确实是进程间通信的管道。

awk/grep/sed