为什么 sed -E find/replace 显示意外输出

Why is sed -E find/replace showing unexpected output

我正在尝试从以下输出中提取 sha256:13b918c5a5eadfed53597146332889dc5e10d1a8edbcdc42f7a872531766aab8。输出位于名为 d2.txt.

的文件中

d2.txt:

The push refers to repository [...]
331ebf1e6bb7: Layer already exists 
9bb0b3c0e55b: Layer already exists 
9f59b9615f5e: Layer already exists 
82621df65774: Layer already exists 
3e123f0af898: Layer already exists 
93defbb4091e: Layer already exists 
bc21254008da: Layer already exists 
53619ba80b4a: Layer already exists 
18eb03bf3058: Layer already exists 
daf4ddfb16e5: Layer already exists 
b5639327d5be: Layer already exists 
30ccd09e6f92: Layer already exists 
167efff21776: Layer already exists 
fee20f1b745d: Layer already exists 
d0fe97fa8b8c: Layer already exists 
v1.0: digest: sha256:13b918c5a5eadfed53597146332889dc5e10d1a8edbcdc42f7a872531766aab8 size: 3470

使用 grep 我可以使用以下内容来识别带有摘要的行:

grep -E '^.*(sha256:[a-z0-9]{64}).*' d2.txt

其中 return 个:

v1.0: digest: sha256:13b918c5a5eadfed53597146332889dc5e10d1a8edbcdc42f7a872531766aab8 size: 3470

使用这个正则表达式中的括号来定义捕获组 1(sha256:hash),我试图在 sed 中 运行 这个。但是我得到的只是摘要中的行,而是 d2.txt 中的所有行。 (在 sha256 行上使用正确的捕获组!)。

sed -E  s/'^.*(sha256:[a-z0-9]{64}).*'/''/g d2.txt

returns:

The push refers to repository [...]
331ebf1e6bb7: Layer already exists 
9bb0b3c0e55b: Layer already exists 
9f59b9615f5e: Layer already exists 
82621df65774: Layer already exists 
3e123f0af898: Layer already exists 
93defbb4091e: Layer already exists 
bc21254008da: Layer already exists 
53619ba80b4a: Layer already exists 
18eb03bf3058: Layer already exists 
daf4ddfb16e5: Layer already exists 
b5639327d5be: Layer already exists 
30ccd09e6f92: Layer already exists 
167efff21776: Layer already exists 
fee20f1b745d: Layer already exists 
d0fe97fa8b8c: Layer already exists 
sha256:13b918c5a5eadfed53597146332889dc5e10d1a8edbcdc42f7a872531766aab8

那么为什么 sed return 全文所有没有正则表达式匹配的行?

您可以使用 grep 和 -o 来只打印匹配的部分。

grep -Eo 'sha256:[[:alnum:]]{64}' d2.txt

或者使用 sed,您可以使用 -n 阻止默认打印,并使用 p 仅打印带有替换的行。

sed -En  's/^.*(sha256:[a-z0-9]{64}).*//p' d2.txt

两者都会输出

sha256:13b918c5a5eadfed53597146332889dc5e10d1a8edbcdc42f7a872531766aab8

使用您展示的示例,在 awk 中使用 awkmatch 函数,您可以尝试以下代码:

awk 'match([=10=],/sha256:[a-z0-9]{64}/){print substr([=10=],RSTART,RLENGTH)}' d2.txt

如果你在整个文件中只有一个匹配并且你想打印它然后使用 exit 也与上面的代码一起使它更快并且我们不需要读取整个文件,

awk 'match([=11=],/sha256:[a-z0-9]{64}/){print substr([=11=],RSTART,RLENGTH);exit}' d2.txt