如何在文本文件中提取/更改数据被分成字段的行?

ter*_*don 9 sed awk perl text-processing

如何从命令行操作基于字段的数据?例如

  • 如何仅打印第 N 个字段为 的行foo
  • 如何仅打印第 N 个字段不是的行foo
  • 如何仅打印第 N 个字段匹配的行foo
  • 如何将字段 N 更改为foo

是否有标准方法或工具集有助于在 *nix 系统上操作基于字段的数据?

ter*_*don 9

处理字段时可以使用两种基本方法:i) 使用理解字段的工具;ii) 使用正则表达式。在这两者中,前者通常更加健壮和简单。

*nix 上的许多常用工具要么是明确设计来处理字段的,要么有一些巧妙的技巧来促进它。

1. 使用了解字段的工具

1.1 周

这里的经典工具是awk. 它会自动分割每个输入线成字段(字段分隔符是空白默认但可以使用被改变-F标志)和字段然后提供给awk脚本,其中是场号。第一个字段是,第二个等等。$nn$1$2

1.2 Perl

另一种选择是perl单线。与 awk 一样,Perl 是一种功能齐全的脚本语言,但也可以作为以脚本为输入的命令行程序运行。它的行为由命令行开关修改,其中与此问题最相关的是:

  • -e:perl应该运行的脚本;
  • -n : 逐行读取输入文件;
  • -p: 在应用给定的脚本后打印每个输入行-e
  • -l: 从每个输入行中删除尾随换行符,并为每个print调用添加一个换行符;
  • -a: awk-mode,将每条输入行拆分成数组@F
  • -F: 的字段分隔符-a

与 的一个重要区别awk是 thatperl-a开关将文件拆分为一个数组。在 Perl 中,数组从 0 开始,而不是 1。这意味着第二个字段实际上是$F[1]而不是$F[2]。考虑到所有这些,perl上面的等价物是:

2. 使用正则表达式

这里的想法是使用正则表达式(简称“regex”)来定义目标字符串在行中的位置。例如,在一个字段由 分隔的文件中:,我们可以通过匹配直到第一个:(第一个字段)的所有内容,然后查找第二个字段来找到第二个字段:

^[^:]*:[^:]*:
Run Code Online (Sandbox Code Playgroud)

这个正则表达式的意思是:

  • ^ : 行首;
  • [^]: 否定字符类。[^:]意思是“除了”之外的任何东西:
  • * : 0 个或多个前一个模式;
  • :: 字面意思:;

综合起来,这意味着第一个[^:]*是第一个字段,第二个是第二个字段。显然,如果您正在寻找第 14 个字段,这不是很实用,但它对于更简单的事情很有用。那么,我们如何实现它来操纵我们的数据呢?有多种工具可以做到这一点;在这些示例中,我将使用,sed但您可以使用awk,perl或做非常相似的事情python