使用 AWK 获取一行中的前 x 个字段

Get the first x fields in a line using AWK

我有一个生成如下输出的命令行实用程序:

Amelia Earhart Dam, Mystic River, Boston Harbor, Massachusetts                               Ref 42.3950∞ N,  71.0767∞ W
Annisquam, Lobster Cove, Massachusetts                                                       Sub 42.6550∞ N,  70.6767∞ W
Barnstable Harbor, Beach Point, Cape Cod Bay, Massachusetts                                  Sub 41.7217∞ N,  70.2850∞ W
Boston Light, Boston Harbor, Massachusetts                                                   Ref 42.3283∞ N,  70.8917∞ W
Boston, Boston Harbor, Massachusetts                                                         Ref 42.3548∞ N,  71.0534∞ W

我需要从行首到州名提取项目(马萨诸塞州可以更改,但我可以输入变量)。

此 AWK 命令获取状态名称之前的所有内容:

awk -F 'Massachusetts' '{print }' stations.txt

如何配置 AWK 命令以包含州名而不是行的其余部分?我想我总是可以 post-process 将状态名称添加到它之前的字段,但是可以这么说,这看起来很尴尬。

使用 sed

可能会更容易
$ sed -r 's/(Massachusetts).*//' file

或者,翻译成 awk

的一种方式
$ awk '{[=11=]=gensub("(Massachusetts).*","\1",1)}1' file 

您的 awk 程序打印第一个 Massachusetts 定界字符串(-F 等于 输入字段分隔符 FS)但是因为没有什么可以分开,不会输出分隔符。如果输出分隔符,awk 将输出 输出字段分隔符 OFS 默认情况下是 space。使用您的方法,您最多可以打印 FSFS:

$ awk -F 'Massachusetts' '{print  FS}' stations.txt

您也可以将州名作为变量并替换从州名到结尾的所有内容 ($):

$ awk -v state="Massachusetts" '{sub(state".*$",state)} 1' stations.txt
Amelia Earhart Dam, Mystic River, Boston Harbor, Massachusetts
Annisquam, Lobster Cove, Massachusetts
Barnstable Harbor, Beach Point, Cape Cod Bay, Massachusetts
Boston Light, Boston Harbor, Massachusetts
Boston, Boston Harbor, Massachusetts

如果您认为 awk 对这项任务来说太过分了,那么 grep 可以做到这一点。

grep -o '^.*Massachusetts' inputfile
Amelia Earhart Dam, Mystic River, Boston Harbor, Massachusetts
Annisquam, Lobster Cove, Massachusetts
Barnstable Harbor, Beach Point, Cape Cod Bay, Massachusetts
Boston Light, Boston Harbor, Massachusetts
Boston, Boston Harbor, Massachusetts

以上代码将从行首 (^) 开始打印,包括 Massachusetts 之前的任何字符。如果您希望有多个字段分隔符,那么

grep -o '^.*(Massachusetts|NEXT-SEPARATOR|ANOTHER-SEPARATOR|Nth-SEPRATOR)' inputfile