linux grep -oP 如何只打印模式
how linux grep -oP print the pattern only
# cat a.file
123123abc file2
274efcc4d8a0e8f61397be46bd4bfa37 file1
321 file1
# file="file1"
# grep -m 1 -oP "\K([\w]+) +$file" a.file
274efcc4d8a0e8f61397be46bd4bfa37 file1
如何使用参数 file1
行获得输出 274efcc4d8a0e8f61397be46bd4bfa37
,并且只使用 grep
命令而不使用 |
或其他命令,如 awk
?
有没有grep -P
有一些其他参数只打印匹配模式\K([\w]+)
比如结果是274efcc4d8a0e8f61397be46bd4bfa37
?或者是否有任何实现仅使用 grep
获得结果。
$ file='file1'
$ grep -m1 -oP '\w+(?= +'"$file"'$)' a.file
274efcc4d8a0e8f61397be46bd4bfa37
(?=regexp)
是一个积极的前瞻结构,它可以帮助您定义一个断言,而无需它成为匹配部分的一部分。有关环顾四周的更多信息,请参阅 Reference - What does this regex mean?。
我还将 '\w+(?= +'
、"$file"
和 '$)'
并排放置,因此只有 shell 变量在双引号下。这里使用 $
锚点来避免部分匹配,例如 file1
vs file1a
或 file11
。如果您的文件名可以包含正则表达式元字符(例如:.
),那么您需要使用 '\w+(?= +\Q'"$file"'\E$)'
来逐字匹配文件名。
不知道为什么你不想在这里使用 awk
,它非常适合这个任务。字符串比较派上用场,可以避免处理正则表达式转义。
awk -v f="$file" '==f{print ; exit}'
你误用了\K
,它会丢弃匹配的文本捕获直到当前时刻,它在模式的开头没有用。 +file1
正在消费模式,它将作为匹配部分返回。
使用非消耗模式:
grep -m 1 -oP "\w+(?=\s+$file\b)" a.file
参见regex proof。 \b
将禁止匹配 file10
.
解释
--------------------------------------------------------------------------------
\w+ word characters (a-z, A-Z, 0-9, _) (1 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
(?= look ahead to see if there is:
--------------------------------------------------------------------------------
\s+ whitespace (\n, \r, \t, \f, and " ") (1
or more times (matching the most amount
possible))
--------------------------------------------------------------------------------
file1 'file1'
--------------------------------------------------------------------------------
\b the boundary between a word char (\w)
and something that is not a word char
--------------------------------------------------------------------------------
) end of look-ahead
# cat a.file
123123abc file2
274efcc4d8a0e8f61397be46bd4bfa37 file1
321 file1
# file="file1"
# grep -m 1 -oP "\K([\w]+) +$file" a.file
274efcc4d8a0e8f61397be46bd4bfa37 file1
如何使用参数 file1
行获得输出 274efcc4d8a0e8f61397be46bd4bfa37
,并且只使用 grep
命令而不使用 |
或其他命令,如 awk
?
有没有grep -P
有一些其他参数只打印匹配模式\K([\w]+)
比如结果是274efcc4d8a0e8f61397be46bd4bfa37
?或者是否有任何实现仅使用 grep
获得结果。
$ file='file1'
$ grep -m1 -oP '\w+(?= +'"$file"'$)' a.file
274efcc4d8a0e8f61397be46bd4bfa37
(?=regexp)
是一个积极的前瞻结构,它可以帮助您定义一个断言,而无需它成为匹配部分的一部分。有关环顾四周的更多信息,请参阅 Reference - What does this regex mean?。
我还将 '\w+(?= +'
、"$file"
和 '$)'
并排放置,因此只有 shell 变量在双引号下。这里使用 $
锚点来避免部分匹配,例如 file1
vs file1a
或 file11
。如果您的文件名可以包含正则表达式元字符(例如:.
),那么您需要使用 '\w+(?= +\Q'"$file"'\E$)'
来逐字匹配文件名。
不知道为什么你不想在这里使用 awk
,它非常适合这个任务。字符串比较派上用场,可以避免处理正则表达式转义。
awk -v f="$file" '==f{print ; exit}'
你误用了\K
,它会丢弃匹配的文本捕获直到当前时刻,它在模式的开头没有用。 +file1
正在消费模式,它将作为匹配部分返回。
使用非消耗模式:
grep -m 1 -oP "\w+(?=\s+$file\b)" a.file
参见regex proof。 \b
将禁止匹配 file10
.
解释
--------------------------------------------------------------------------------
\w+ word characters (a-z, A-Z, 0-9, _) (1 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
(?= look ahead to see if there is:
--------------------------------------------------------------------------------
\s+ whitespace (\n, \r, \t, \f, and " ") (1
or more times (matching the most amount
possible))
--------------------------------------------------------------------------------
file1 'file1'
--------------------------------------------------------------------------------
\b the boundary between a word char (\w)
and something that is not a word char
--------------------------------------------------------------------------------
) end of look-ahead