Sample Input:
title role subject
name-JOHN student math
school state NY
county street Phone
name-TOM student math
school state TX
county street Phone
name-LILLY student math
school state LA
county street Phone
name-ROSY student math
school state WA
county street Phone
garbage line 1
garbage line 2
Desired Output
JOHN NY
TOM TX
LILLY LA
ROSY WA
底部 2 条垃圾线必须消失。我想使用 AWk 还是 SED?
我正在运行 Sun 操作系统。
答案1
由 GNU 提供sed
sed -n '/^name-/{s///;N;s/[a-z].*\s//p}' file
JOHN NY
TOM TX
LILLY LA
ROSY WA
由 GNU 提供awk
awk -F'[ -]+' '/name/{a=$2}/state/{print a,$3}' OFS='\t' file
JOHN NY
TOM TX
LILLY LA
ROSY WA
经过grep
grep -o '[[:upper:]]\{2,\}' file | paste - -
JOHN NY
TOM TX
LILLY LA
ROSY WA
答案2
这是另一种 awk 方式(我现在看到,这只是 @Costas 的一个丑陋版本):
$ awk -F'[- ]' '($1~/name/){k=$2}($1~/school/){print k,$NF}' file
JOHN NY
TOM TX
LILLY LA
ROSY WA
您还可以使用grep
:
$ grep -oP '^(name-\K\S+|school.*\s+\K.*)' file | paste - -
JOHN NY
TOM TX
LILLY LA
ROSY WA
当然,在您的特定示例中,您可以只查找大写字母:
$ grep -Eo '[A-Z]{2,}' file | paste - -
或者perl:
$ perl -lne '$n=$1 if /^name-(\S+)/; /^school.*\s+(.+)/ && print "$n\t$1"' file
或者另一个 perl:
$ perl -007ne 'print join "\n", (/name-(\S+?)\s.*?state\s+(..)\n/gsm)' file | paste - -
答案3
awk '/name/ {gsub(/name-/,""); printf "%s\t",$1} /school/ {print $3}' file
JOHN NY
TOM TX
LILLY LA
ROSY WA
答案4
需要明确的是,您使用的是“旧awk
”( /usr/bin/awk/
) 还是“新awk
”( /usr/xpg6/bin/awk
)?一个在线的手册页参考和GNU Awk 的帮助页面非常清楚地指出了区别。
假设如果您指的是“new awk
”,您可以通过使用变量赋值-v
,您也可以考虑这一点:
$ awk -v RS='name-' -v OFS='\t' 'NR>1{print $1,$6}' sample.txt
JOHN NY
TOM TX
LILLY LA
ROSY WA
我们设置记录分隔符 ( -v RS='name-'
),以便awk
将名称和状态分别解释为第一个 ( $1
) 和第六个 ( $6
) 字段。然后我们还设置输出字段分隔符 ( -v OFS='\t'
) 以执行所需的格式设置。条件NR>1
只是跳过第一行。
编辑
awk 'BEGIN{RS="name-";OFS="\t"}NR>1{print $1,$6}' sample.txt
即使对于“老”来说这也应该是可行的awk
,请测试一下。保持“新awk
”的最初建议不变。