grep 搜索从 1900 年到 2100 年的年份?
例如,如果我有一个带有20123320
的变量,我想打印2012
.
使用 bash 的有趣方法(sh
用户当心!
如果要匹配并打印出现在文件file
行首的所有年份:
printf "^%sn" {1900..2100} | grep -of - file
如果您有包含 20123320
的变量variable
:
variable=20123320
printf "^%sn" {1900..2100} | grep -of - <(echo "$variable")
现在,请详细说明您想要做的确切内容,以便我们为您提供最合适的答案。
当我看到使用bash和grep以外的其他工具的其他答案时,这是一个100%的bash解决方案:
variable="20123320"
# take the first 4 characters of variable:
year="${variable:0:4}"
# check that year is an integer and that it falls into the given range
if [[ "$year" =~ ^[[:digit:]]+$ ]] && (( 1900<=year && year<=2100)); then
echo "$year"
else
# Do whatever you want here
echo "You dumbo, I couldn't find a valid year in your string"
fi
awk 'BEGIN{FIELDWIDTHS="4 "}{if($1~/^[0-9]+$/&&$1>=1900&&$1<=2100)print $1}'
尝试这样做:
echo "$var" | grep -Eo 'b(((19|20)[0-9][0-9])|2100)'
或者看看我的perl解决方案,因为我认为在这里使用regex
不是最好的途径。
如果你坚持使用grep
,你可以。
我假设您要匹配 1900 到 2100 范围内以 4 位数字开头的变量,并且您只想打印这 4 位数字。
echo "$var" | grep -Eo '^(((19|20)[0-9][0-9])|2100)'
这忽略了前 4 位数字后面可能出现的任何内容(因为我想不出一种在不打印的情况下检查字符串其余部分的方法)。
但是grep
不是这项工作的明显工具,正则表达式也不是匹配一系列数字的最佳工具。例如,如果需要匹配从 1950 到 2100 的数字,则正则表达式必须大不相同。
就个人而言,我会使用Perl:
echo "$var" | perl -ne 'if (/^(d{4})d{4}$/ and $1 >= 1900 and $1 <= 2100) { print "$1n" }'
这将检查$var
是否正好包含 8 个十进制数字。如果要检查它们是否构成有效日期,则需要更多代码。
你也可以在awk中相当干净地做到这一点,这可能会更快一些。
grep 不是更好的工具,Perl 将更适合、更容易和健壮地测试数字范围:
echo "$var" | perl -lne '
$year = substr($_, 0, 4);
print $year if $year <= 2100 && $year >= 1900 && $year =~ /^d+$/
'
或具有相同逻辑的awk:
echo "$var" | awk '
{
year = substr($0, 0, 4)
if (year <= 2100 && year >= 1900 && $1 ~ /^[0-9]+$/) {
print year
}
}'