假设我必须从输入文件执行这些操作:
从以给定模式开头的行中提取第 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