动态更改less/tail的grep参数

54次阅读
没有评论

问题描述

在使用tail命令追踪日志文件时,我们可能会使用以下命令:

tail -f foo.log | grep bar

如果我们想要改变grep的参数,我们必须使用Ctrl+C终止命令,然后更改参数,再重新启动命令。
我的问题是:是否有一种方法可以在不终止tailgrep命令的情况下动态更改我们要搜索的内容?如果可能,还想知道如何在使用less而不是tail时实现这一点。

解决方案

以下方案基于提供的回答和知识库,可能存在版本差异,请注意进行适当的调整。

使用Node.js实现动态更改grep参数

通过Node.js可以实现动态更改grep参数,以避免终止命令。以下是一种实现方法,你可以通过一个名为dygrep的工具来实现:
1. 在终端1中运行以下命令启动多个子进程并将其输出写入日志文件logfile.log
bash
many-child-procs > logfile.log

2. 在终端2中,使用tailgrep命令来过滤输出:
bash
tail -f logfile.log | grep <expression>

3. 使用dygrep连接到TCP服务器,以控制过滤的表达式。

下面是基于Node.js实现的dygrep工具的简要示例代码:

#!/usr/bin/env node
'use strict';

import * as readline from 'readline';
import * as net from 'net';
import chalk from 'chalk';
import { createParser } from "./json-parser";
import log from './logger';

let port = 4900;

const rl = readline.createInterface({
  input: process.stdin.resume()
});

const regex = new Map<string, RegExp>();

rl.on('line', l => {
  if (regex.size < 1) {
    process.stdout.write(l + '\n');
    return;
  }

  for (let [k, v] of regex) {
    if (v.test(l)) {
      process.stdout.write(chalk.magenta(' (filtered) ') + l + '\n');
      break;
    }
  }
});

interface IncomingTCPMessage {
  command: {
    add: string,
    remove: string,
    list: boolean,
    removeall: boolean
  }
}

const server = net.createServer(s => {
  const sendMessage = (m: any) => {
    s.write(JSON.stringify({ message: m }) + `\n`);
  };

  s.pipe(createParser()).on('data', (d: IncomingTCPMessage) => {
    if (!d.command) {
      log.error('No "command" field was found:', d);
      return ''
    }

    const c = d.command;

    if (c.list) {
      sendMessage({ regexes: Array.from(regex.keys()).map(k => ({ regex: regex.get(k), str: k })) });
      log.info('Listing all regex for the client.');
      return;
    }

    if (c.removeall) {
      regex.clear();
      sendMessage(`Cleared all regex.`);
      log.info('Cleared all regex.');
      return;
    }

    if (c.add) {
      regex.set(c.add, new RegExp(c.add));
      sendMessage(`Added regex: ${c.add}.`);
      log.info('Added regex:', c.add);
      return;
    }

    if (c.remove) {
      regex.delete(c.remove);
      sendMessage(`Deleted regex: ${c.remove}.`);
      log.info('Removed regex:', c.remove);
      return;
    }

    log.error('No matching field was found:', d);
    log.info('Regex:', regex);
  });
});

server.listen(port);

通过以上步骤,你可以实现动态更改grep参数而不需要终止tail命令。具体步骤涉及启动dygrep工具以连接到TCP服务器,然后可以通过发送不同的命令来控制过滤的表达式。

请注意,此方案基于Node.js和dygrep工具的实现。你可以在项目的GitHub仓库(https://github.com/ORESoftware/dygrep)中找到完整的代码和详细信息。

以上就是动态更改less/tailgrep参数的解决方案,希望能够帮助你实现这一功能。

正文完