我正在尝试提取并打印我匹配的特定单词之前出现的单词。举个例子,
There are 12 processes running.
在这里,我使用 sed 搜索单词processes
,我只想打印12
。
这可以使用吗sed
?
答案1
如果您只需要处理这一行,您可以使用 sed 命令
sed -e 's/.* \([[:digit:]]\{1,\}\) processes running\./\1/'
对于稍微更稳健的方法,以下脚本将接受任意输入,并且仅在匹配时才响应
sed -ne 's/.* \([[:digit:]]\{1,\}\) processes running\./\1/p'
答案2
sed
您可以只使用固定字符串grep
搜索,而不是使用复杂的替换cut
:
$ grep -F 'processes' file | cut -d ' ' -f 3
答案3
据我所知,您只需要找到任何单词(在常见情况下)并在之前打印单词即可。
解决方案GNU sed
:
sed -rn 's/(^|(.* ))([^ ]*) YOUR_WORD(( .*)|$)/\3/; T; p; q'
解释
-r
是扩展的 GNU 正则表达式;
-n
是不打印的命令;
(^|(.* ))
— 在要打印的单词之前添加前缀。可以是行首 ( ^
) 或 ( |
) 空格结束字符 ( (.* )
);
([^ ])*)
— 将打印的单词 ( \3
);
YOUR_WORD
— 在您找到的单词之后将其替换为单词。 (就像“进程”之后的“运行”);
(( .*)|$)
$
— 单词、结束符 ( ) 或空格和一些字符之后的行结束符;
\3
找到单词;
T
是“如果替换未成功则跳转到末尾”,GNU 扩展。它将跳转到每行脚本的末尾,不包含YOUR_WORD
非第一个单词;
p
是“打印缓冲区”,打印找到的单词(如果T
在这一行不起作用);
q
是停止执行的命令sed
,因为我们已经找到了单词(没有用 跳转T
)并且我们不需要找到新单词。
更新:没有 GNU 扩展的解决方案
sed -n 's/\(^\|\(.* \)\)\([^ ]*\) YOUR_WORD\(\( .*\)\|$\)/\3/; tprint; b; :print; p; q
解释是一样的,区别在于反斜杠和t
。t
作为T
,但如果替换则跳转曾是成功的。如果是这样,我们跳转到“打印并退出”,如果不是,则b
发送至脚本和下一行处理。