我有一个 grep 适用于某些日期,但无法让我的大脑充分发挥其功能。
grep 19[6-9][5-6]$ filename
它正确地捕获了一些,但我希望捕获 1965 年至 1996 年之间的所有年份。
这是当前的解决方案,但实际上是在寻找一行,但这是我迄今为止得到的:
grep 196[5-9]$ filename
grep 197[0-9]$ filename
grep 198[0-9]$ filename
grep 199[0-6]$ filename
如果可能的话,寻找更好、更短的?
答案1
日期范围和正则表达式并不是很好的匹配。如果我正确解释 grep 中的 $,则日期是一行中的最后一个字段。
尝试这个:
awk '$NF >= 1965 && $NF <= 1996' filename
如果你必须使用 grep ,它会变得更加复杂:
grep -E '196[5-9]|19[78][0-9]|199[0-6]$' filename
答案2
您应该注意,egrep
允许19
将 分解出来,如下所示:
grep -E '19(6[5-9]|[78][0-9]|9[0-6])$' filename
这可能被认为更清楚。
答案3
您也可以使用seq
我发现更具可读性的:
grep -E "$(seq -s "|" 1965 1996)" filename
-s, --separator=字符串
答案4
使用标准grep
语法提取以 1965 到 1996 范围内的任何子字符串数字结尾的行(这也是相似的问题中用户的尝试):
grep -e '196[5-9]$' \
-e '197[0-9]$' \
-e '198[0-9]$' \
-e '199[0-6]$'
这会提取以您感兴趣的任何数字结尾的行。请注意,表达式通常应该加引号。
为了避免在行尾匹配eg 231974
(与)匹配,您可能需要在模式中每个数字的开头插入:1974
\<
grep -e '\<196[5-9]$' \
-e '\<197[0-9]$' \
-e '\<198[0-9]$' \
-e '\<199[0-6]$'
这会强制数字成为一个单词,而不是其他较长单词的子串。