使用cut、awk、grep和sed的基础知识

3
我正在尝试从以下输出中提取年份:

2019年11月8日

sam@sam-laptop:~/shell$ date
Mon Feb  8 21:57:00 CET 2010

sam@sam-laptop:~/shell$ date | cut -d' ' -f7
2010

sam@sam-laptop:~/shell$ date | awk '{print $6}'
2010

有没有其他方法可以得到相同的结果?例如使用grep、sed等工具? 谢谢!
6个回答

10

如果你只是想从date中获取当前年份,你可以直接执行以下代码。

date +%Y

无需后期处理。 :)


更新: 关于文本处理的评论(因为原帖作者正在寻找相关信息)

cut / awk / sed 很适合拆解文本行。 grep 适用于查找所需行。

更为模糊(并且不太便携)的是bash特定的类正则表达式运算符,但它们可以快速而有趣地使用。

$ MYDATE=`date`
$ echo $MYDATE
Mon Feb 8 16:28:04 EST 2010
$ echo ${MYDATE##* }
2010

当你发布这个答案时,我正在输入完全相同的答案。唯一需要补充的是阅读手册以获取更多格式选项。事实上,我会说现在nour有一个“授权”去阅读手册了。 - mmrobins
2
$() 比反引号更易于使用且容错率更高(考虑引号和转义)。 - Roger Pate

2

一些 sed 的变体:

date | sed 's/.* //'

date | sed 's/.*\(....\)$/\1/'

date | sed 's/.*\(.\{4\}\)$/\1/'

date | sed -r 's/.*(.{4})$/\1/'

date | sed -r 's/.*([[:digit:]]{4})$/\1/'

1

grep 可以在文件中查找模式。但是,它不会修改您的文件。 sed 除了查找模式外,还可以修改您的文件。 cut 是一个工具,用于“剪切”文件中的列以进行显示/(或写入文件)。如果您的任务非常简单,只需要获取一些列,则可以使用它。 awk 可以在文件中查找模式,并通过创建另一个文件对其进行修改。awk 执行 sed、grep、cut 的功能,因此您可以仅使用一个工具完成几乎所有操作。

对于大型文件,请使用 grep 查找模式并将其传输到 awk/sed 以操纵文本。

例如,如果您想要获取 date 命令的年份,请使用 date +%Y

有多种方法可以获取 date 命令的年份。

$ date +%Y
2010

$ date | awk '{print $NF}'
2010

$ var=$(date)
$ set -- $var
$ eval echo \${${#}}
2010

最后,您可以像一些sed示例那样使用正则表达式,但我发现最简单的方法是拆分字段并获取最后一个字段。不需要复杂的正则表达式。

1

使用GNU grep,您可以使用-o(--only-matching)仅显示与模式匹配的匹配行的部分。下面是一个Perl正则表达式(-P,--perl-regexp),用于连续四个数字:

$ date | grep -oP '\d{4}'
2010

1

Grep旨在打印与RE匹配的整行。让它仅打印一行的一部分将相对困难(至少如此)。

使用sed,您可以使用与其余行匹配的RE,并将其替换为无,留下您关心的部分。


嗯,让GNU grep仅打印出一行的部分并不难。尝试使用“-o”(--only-matching)标志。 - Philip Durbin
@Philip:谢谢你—我之前没有注意到那个标志(虽然我可能已经看过几百次的帮助文本...) - Jerry Coffin

1
你可能想要查看一下Perl。它在语法上很大程度上借鉴了sedawk,是一种完整的编程语言,并且有一个巨大的库(CPAN),可以帮助你与各种不同的系统集成。
当我发现我的简单awk/sed解决方案需要扩展到更复杂的情况时,我转向了Perl。

许多其他的Shell脚本语言(这意味着你可以使用shebang行)出于类似的原因也能很好地工作。 - Roger Pate
非常正确。我个人偏好 Perl,但我也意识到这是基于历史原因而已。今天,我可能会选择 Ruby/Python 等其他语言。 - Brian Agnew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接