我应该使用 cut 还是 awk 来提取字段和字段子字符串?

Posted

技术标签:

【中文标题】我应该使用 cut 还是 awk 来提取字段和字段子字符串?【英文标题】:Should I use cut or awk to extract fields and field substrings? 【发布时间】:2014-05-12 15:10:02 【问题描述】:

我有一个带有管道分隔字段的文件。我想打印字段 1 的子集和字段 2 的所有内容:

cat tmpfile.txt

# 10 chars.|variable length num|text
ABCDEFGHIJ|99|U|HOMEWORK
JIDVESDFXW|8|C|CHORES
DDFEXFEWEW|73|B|AFTER-HOURS

我希望输出如下所示:

# 6 chars.|variable length num
ABCDEF|99
JIDVES|8
DDFEXF|73

我知道如何获取字段 1 和 2:

cat tmpfile.txt | awk 'FS="|" print $1"|"$2'

并且知道如何获取字段 1 的前 6 个字符:

cat tmpfile.txt | cut -c 1-6

我知道这很简单,但我不知道如何组合awkcut 命令。

任何建议将不胜感激。

【问题讨论】:

【参考方案1】:

您可以使用awk。使用substr() 函数修剪第一个字段:

awk -F'|' 'print substr($1,1,6),$2' OFS='|' inputfile

对于您的输入,它会产生:

ABCDEF|99
JIDVES|8
DDFEXF|73

使用sed,你可以说:

sed -r 's/^(.6)[^|]*([|][^|]*).*/\1\2/' inputfile

产生相同的输出。

【讨论】:

+1;略短:awk -F'|' 'print substr($1,1,6) FS $2' inputfile 如果短很重要:awk -F\| '$0=substr($1,1,6)FS$21' 谢谢 - 在这种情况下,“1”(不是 $1)是什么意思? @user3486154 你可以认为它等同于print @Jotne 为什么还要麻烦大括号和1awk -F\| '$0=substr($1,1,6)FS$2' 应该足够了。 ;)【参考方案2】:

我喜欢 cut 和 sed 的组合,但这只是一种偏好:

cut -f1-2 -d"|" tmpfile.txt|sed 's/\([A-Z]\6\\)[A-Z]\4\/\1/g'

结果:

# 10-digits|variable length num
ABCDEF|99
JIDVES|8
DDFEXF|73

编辑:(删除无用的猫)谢谢!

【讨论】:

【参考方案3】:

只是为了另一个变化:awk -F\| -vOFS=\| 'print $1,$2' t.in | cut -c 1-6,11-

此外,正如 Tripleee 指出的那样,两次切割也可以做到这一点:cut -c 1-6,11- t.in | cut -d\| -f 1,2

【讨论】:

或者如果你可以猜测第二个字段的最大长度,使用两次切割; cut -c1-6,11-16 t.in | cut -d'|' -f1-2【参考方案4】:

可以使用剪切和粘贴,但是您必须读取两次文件,如果文件很大,这很重要:

paste -d '|' <(cut -c 1-6 tmpfile.txt ) <(cut -d '|' -f2 tmpfile.txt )

【讨论】:

以上是关于我应该使用 cut 还是 awk 来提取字段和字段子字符串?的主要内容,如果未能解决你的问题,请参考以下文章

cut 或 awk 命令打印第一行的第一个字段

获取文本中你须要的字段的 几个命令 grep awk cut tr sed

从文本文件中提取结构化数据(awk?):缺少的字段必须获得默认值

使用 bash 命令 awk sed 等从脚本中提取参数字段

Shell工具cut/sed/awk/sort

利用awk命令提取其中一列包括特定字符的所有行怎么办