模式和文件处理

模式和文件处理

假设我必须从输入文件执行这些操作:

  • 从以给定模式开头的行中提取第 n 个字段(在示例中:以模式“name”开头的行的第二个字段

  • 在接下来的每一行的开头打印字段内容,而该行确实不是从选定的图案开始

  • 当找到与模式匹配的新行时,重复步骤 1 和 2

我目前正在使用 Python 执行此操作,但使用命令行中的轻量级快速命令(例如 awk)会更好。

输入样本

name    NAME_A
inf     field_A1
name    NAME_B 
inf field_B1
inf field_B2

预期输出:

name    NAME_A
NAME_A  inf field_A1
name    NAME_B 
NAME_B  inf field_B1
NAME_B  inf field_B2

答案1

这可以是一种方法。请注意,格式可能会有所不同,具体取决于您指定的字段分隔符 - 您可以使用FS和定义字段分隔符OFS

$ awk -v n=2 '/^name/ {a=$(n); print; next} {print a, $0}' file
name    NAME_A
NAME_A inf  field_A1
name    NAME_B 
NAME_B inf  field_B1
NAME_B inf  field_B2

解释

  • -v n=2定义找到模式时要复制的字段号。
  • /^name/ {a=$(n); print; next}如果该行以给定模式开头,则存储给定字段并打印该行。
  • {print a, $0}否则,首先使用存储的值打印当前行。

您可以将模式部分概括为:

awk -v n=2 -v pat="name" '$1==pat {a=$(n); print; next} {print a, $0}' file

答案2

sed '/^name  */{h;s///;x;n;};G;s/\(.*\)\n\(.*\)/\2        \1/' <<\DATA
name    NAME_A
inf     field_A1
name    NAME_B 
inf field_B1
inf field_B2
DATA

输出

name    NAME_A
NAME_A  inf     field_A1
name    NAME_B 
NAME_B  inf field_B1
NAME_B  inf field_B2

sed h老每姓名行,然后从相同的模式中删除与之匹配的任何模式,然后在打印之前交换保留空间和模式空间,

在每隔一行上,它将G保留空间附加到模式空间并插入换行符。然后它只是交换换行符的两侧并用制表符替换它。

答案3

这可能有效:

awk '{print $0 ~ pat ? $0 : p OFS $0   }$0 ~ pat{ p = $NF }' pat='name' file

相关内容