繁体   English   中英

正则表达式作为 awk 中的字段分隔符

[英]Regular expression as field delimiter in awk

我有一个包含 586696 行和 40 列的大型数据集。 但是,我只对其中一些列感兴趣。 一个里面有名字,另一个里面有数字。

我很难处理这个文件中的字段分隔符。 所有的列分隔符都是空格。 如果你假设我的文件名为test.txt并且里面有 5 个人,它看起来像这样:

Name Salary
FirstName01 LastName01 Salary01
FirstName02 MiddleName02 LastName02 Salary02
FirstName03 MiddleName03 LastName03 Salary03
FirstName04 LastName04 Salary04
FirstName05 MiddleName05 LastName05 Salary05

因此,如果我跑

awk '{print $1 " " $2}' test.txt

结果是

Name Salary
FirstName01 LastName01
FirstName02 MiddleName02
FirstName03 MiddleName03
FirstName04 LastName04
FirstName05 MiddleName05

但我想要的是

Name Salary
FirstName01 LastName01 Salary01
FirstName02 MiddleName02 LastName02 Salary02
FirstName03 MiddleName03 LastName03 Salary03
FirstName04 LastName04 Salary04
FirstName05 MiddleName05 LastName05 Salary05

为了解决这个问题,假设在列Name之前和列Salary之后有列。

我该如何解决我的问题? 我想我必须使用一些正则表达式作为字段分隔符才能在这里使用 awk,但我找不到办法做到这一点。

编辑:我想我在原帖中没有说清楚。 我知道 awk 正是我所要求的。 我的问题是我的完整数据集类似于

Column01 Column02 Column03 Name Salary Column06 ...
Text0101 Text0102 Text0103 FirstName01 LastName01 Salary01 ...
Text0201 Text0202 Text0203 FirstName02 MiddleName02 LastName02 Salary02 ...
Text0301 Text0302 Text0303 FirstName03 MiddleName03 LastName03 Salary03 ...
Text0401 Text0402 Text0403 FirstName04 LastName04 Salary04 ...
Text0501 Text0502 Text0503 FirstName05 MiddleName05 LastName05 Salary05 ...

鉴于上表,我想要一个可以产生以下结果的 awk 代码:

Name Salary
FirstName01 LastName01 Salary01
FirstName02 MiddleName02 LastName02 Salary02
FirstName03 MiddleName03 LastName03 Salary03
FirstName04 LastName04 Salary04
FirstName05 MiddleName05 LastName05 Salary05

抱歉我的误导性问题。

根据@jas 评论:您可以使用 awk 中的 NF 变量检查列数。 所以这样的事情应该为你的 test.txt 做诀窍

awk '{name=$4; for (i = 5; i <= NF - 2; i++) name=name " " $i; salary=$i; print name " " salary}' test.txt

这将打印名称(从第 4 列开始)并将每一列添加到名称的最后第三列。 倒数第二列将是薪水。

当然,您必须根据需要调整 'name=$4'、'i = 5' 和 'NF - 2' 中的值。

正如其他人指出的那样,最好以某种方式更改生成数据集的算法,以便获得唯一的字段分隔符。

你的问题是原始格式不好! 如果名称是唯一一列扩展到多个字段,您可以检查每行中的字段数并修改列选择。

awk 'NR==1{c=NF} {t=$4; for(i=5;i<6+(NF-c);i++) t=t " " $i; print t}' badformat.txt

如果您的其他“列”都不包含空格,并且每行中的“列”数始终相同,那么解决此问题的方法是从字段 X 开始并将字段打印到 (NF-Y)。 这样,名称的每个“列”中包含多少字段并不重要,因为端点由名称后应保留的列数决定。

如果您的输入不是那样 - 编辑您的问题以向我们展示它的真实情况!

这似乎适用于您提供的样本输入,但对于您的实际输入可能完全错误,因为您提供的样本不包含实际输入中可能存在的值,并且在第一条记录和其余记录之间内部不一致在外地职位方面:

$ awk '{e=NF-1; for (i=4;i<=e;i++) printf "%s%s", $i, (i<e?OFS:ORS)}' file
Name Salary
FirstName01 LastName01 Salary01
FirstName02 MiddleName02 LastName02 Salary02
FirstName03 MiddleName03 LastName03 Salary03
FirstName04 LastName04 Salary04
FirstName05 MiddleName05 LastName05 Salary05

上面是在这个输入文件上运行的,该文件修改了第一行以使其至少与您的后续行保持一致:

$ cat file
Column01 Column02 Column03 Name Salary ...
Text0101 Text0102 Text0103 FirstName01 LastName01 Salary01 ...
Text0201 Text0202 Text0203 FirstName02 MiddleName02 LastName02 Salary02 ...
Text0301 Text0302 Text0303 FirstName03 MiddleName03 LastName03 Salary03 ...
Text0401 Text0402 Text0403 FirstName04 LastName04 Salary04 ...
Text0501 Text0502 Text0503 FirstName05 MiddleName05 LastName05 Salary05 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM