脚本如何实现文件内容过滤功能

wen 实用脚本 1

本文目录导读:

脚本如何实现文件内容过滤功能

  1. 使用 grep 命令(最常用)
  2. 使用 sed 命令
  3. 使用 awk 命令(高级过滤)
  4. Python 脚本实现
  5. 完整功能脚本示例
  6. 性能优化的流式处理
  7. 使用建议

使用 grep 命令(最常用)

# 基本用法
grep "keyword" file.txt
# 递归搜索目录
grep -r "keyword" /path/directory/
# 忽略大小写
grep -i "keyword" file.txt
# 显示行号
grep -n "keyword" file.txt
# 反向匹配(排除)
grep -v "keyword" file.txt
# 多关键字匹配(或)
grep -E "keyword1|keyword2" file.txt
# 多关键字匹配(与)
grep "keyword1" file.txt | grep "keyword2"

使用 sed 命令

# 删除包含特定内容的行
sed '/keyword/d' file.txt
# 只显示匹配的行
sed -n '/keyword/p' file.txt
# 替换并显示
sed 's/old/new/g' file.txt
# 行范围过滤
sed -n '10,20p' file.txt

使用 awk 命令(高级过滤)

# 基于模式过滤
awk '/pattern/ {print $0}' file.txt
# 基于列过滤(第2列大于100)
awk '$2 > 100' file.txt
# 多条件过滤
awk '$1 ~ /pattern/ && $3 > 50' file.txt
# 自定义分隔符
awk -F: '$3 == 0 {print $1}' /etc/passwd

Python 脚本实现

#!/usr/bin/env python3
import re
import sys
def filter_file(filename, pattern, options=None):
    """文件内容过滤器"""
    results = []
    with open(filename, 'r') as f:
        for line_num, line in enumerate(f, 1):
            if options and options.get('case_insensitive'):
                match = re.search(pattern, line, re.IGNORECASE)
            else:
                match = re.search(pattern, line)
            if options and options.get('invert'):
                if not match:
                    results.append((line_num, line.rstrip()))
            else:
                if match:
                    results.append((line_num, line.rstrip()))
    return results
# 使用示例
if __name__ == "__main__":
    # 基础过滤
    matches = filter_file("test.txt", "error")
    # 忽略大小写
    matches = filter_file("test.txt", "error", {'case_insensitive': True})
    # 反向过滤
    matches = filter_file("test.txt", "comment", {'invert': True})
    # 高级过滤
    class AdvancedFilter:
        def __init__(self, filename):
            self.filename = filename
        def filter_by_size(self, min_size=0, max_size=float('inf')):
            """按行长度过滤"""
            results = []
            with open(self.filename, 'r') as f:
                for line in f:
                    if min_size <= len(line) <= max_size:
                        results.append(line.rstrip())
            return results
        def filter_by_patterns(self, patterns, logic='AND'):
            """多模式过滤"""
            results = []
            with open(self.filename, 'r') as f:
                for line in f:
                    if logic == 'AND':
                        if all(p in line for p in patterns):
                            results.append(line.rstrip())
                    elif logic == 'OR':
                        if any(p in line for p in patterns):
                            results.append(line.rstrip())
            return results
        def filter_by_regex(self, pattern, columns=None):
            """正则表达式过滤,可指定列"""
            results = []
            with open(self.filename, 'r') as f:
                for line in f:
                    if columns:
                        fields = line.split()
                        for col in columns:
                            if col < len(fields) and re.search(pattern, fields[col]):
                                results.append(line.rstrip())
                                break
                    else:
                        if re.search(pattern, line):
                            results.append(line.rstrip())
            return results
    # 使用高级过滤器
    af = AdvancedFilter("data.txt")
    filtered = af.filter_by_patterns(["ERROR", "CRITICAL"], logic="OR")

完整功能脚本示例

#!/bin/bash
# 多功能文件过滤器
usage() {
    echo "用法: $0 [选项] 文件名"
    echo "选项:"
    echo "  -p, --pattern PATTERN    要匹配的模式"
    echo "  -v, --invert             反向匹配"
    echo "  -i, --ignore-case        忽略大小写"
    echo "  -n, --line-number        显示行号"
    echo "  -c, --count              只显示匹配行数"
    echo "  -o, --output FILE        输出到文件"
    echo "  -h, --help               显示帮助"
}
# 解析参数
while [[ $# -gt 0 ]]; do
    case $1 in
        -p|--pattern)
            PATTERN="$2"
            shift 2
            ;;
        -v|--invert)
            INVERT=true
            shift
            ;;
        -i|--ignore-case)
            IGNORE_CASE=true
            shift
            ;;
        -n|--line-number)
            LINE_NUMBER=true
            shift
            ;;
        -c|--count)
            COUNT=true
            shift
            ;;
        -o|--output)
            OUTPUT="$2"
            shift 2
            ;;
        -h|--help)
            usage
            exit 0
            ;;
        *)
            FILENAME="$1"
            shift
            ;;
    esac
done
# 检查参数
if [[ -z "$PATTERN" || -z "$FILENAME" ]]; then
    echo "错误: 必须指定模式和文件名"
    usage
    exit 1
fi
# 构建grep命令
GREP_OPTS=""
[[ "$INVERT" ]] && GREP_OPTS+=" -v"
[[ "$IGNORE_CASE" ]] && GREP_OPTS+=" -i"
[[ "$LINE_NUMBER" ]] && GREP_OPTS+=" -n"
[[ "$COUNT" ]] && GREP_OPTS+=" -c"
[[ -n "$OUTPUT" ]] && GREP_OPTS+=" > $OUTPUT"
# 执行过滤
eval "grep $GREP_OPTS \"$PATTERN\" $FILENAME"
# 使用示例:
# ./filter.sh -p "ERROR" -i -n app.log
# ./filter.sh -p "test" -v data.txt
# ./filter.sh -p "pattern" -o result.txt input.txt

性能优化的流式处理

#!/usr/bin/env python3
import mmap
import re
def fast_filter(filename, pattern):
    """使用内存映射实现快速过滤"""
    with open(filename, 'rb') as f:
        # 内存映射文件
        with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm:
            for match in re.finditer(pattern.encode(), mm):
                # 获取匹配行的上下文
                start = max(0, match.start() - 100)
                end = min(len(mm), match.end() + 100)
                context = mm[start:end].decode('utf-8', errors='ignore')
                yield context
# 流式处理大型文件
def stream_filter(filename, pattern, chunk_size=8192):
    """使用分块读取处理大型文件"""
    buffer = ""
    with open(filename, 'r') as f:
        while True:
            chunk = f.read(chunk_size)
            if not chunk:
                break
            buffer += chunk
            lines = buffer.split('\n')
            # 保留最后一个不完整的行
            buffer = lines[-1]
            # 处理完整的行
            for line in lines[:-1]:
                if re.search(pattern, line):
                    yield line
            # 处理最后一个不完整的行(如果文件结束)
            if not chunk:
                if re.search(pattern, buffer):
                    yield buffer

使用建议

  1. 小型文件:使用 grep 或 sed,性能最好
  2. 中型文件:Python 脚本提供更多灵活性
  3. 大型文件:使用流式处理或内存映射
  4. 实时监控:结合 tail -f 和 grep -f
  5. 日志分析:awk 适合结构化数据过滤

选择合适的工具取决于你的具体需求(文件大小、复杂度、性能要求等)。

抱歉,评论功能暂时关闭!