如何使用 grep/sed/awk,从文本文件的开头删除模式

How to use grep/sed/awk, to remove a pattern from beginning of a text file

我有一个文本文件,其中写入了以下模式:

TIME[32.468ms]  -(3)-............."TEXT I WANT TO KEEP"

我想丢弃包含

的每一行的第一部分
TIME[32.468ms]  -(3)-.............

为了测试正则表达式,我尝试了以下操作:

cat myfile.txt | egrep "^TIME\[.*\]\s\s\-\(3\)\-\.+"

这正确识别了我想要的行。现在,要删除我尝试过的模式:

cat myfile.txt | sed s/"^TIME\[.*\]\s\s\-\(3\)\-\.+"//

但它似乎只是在执行 cat,因为它显示了完整文件的内容并且没有发生替换。

我做错了什么?

OS: 分OS 7

使用您显示的示例,请尝试执行以下 grep 命令。使用 GNU grep.

编写和测试
grep -oP '^TIME\[\d+\.\d+ms\]\s+-\(\d+\)-\.+\K.*' Input_file

说明:为以上代码添加详细说明。

^TIME\[          ##Matching string TIME from starting of value here.
\d+\.\d+ms\]     ##Matching digits(1 or more occurrences) followed by dot digits(1 or more occurrences) followed by ms ] here.
\s+-\(\d+\)-\.+  ##Matching spaces91 or more occurrences) followed by - digits(1 or more occurrences) - and 1 or more dots.
\K               ##Using \K option of GNU grep to make sure previous match is found in line but don't consider it in printing, print next matched regex part only.
.*               ##to match till end of the value.


第二个解决方案:在此处添加awk程序。

awk 'match([=12=],/^TIME\[[0-9]+\.[0-9]+ms\][[:space:]]+-\([0-9]+\)-\.+/){print substr([=12=],RSTART+RLENGTH)}' Input_file

解释:使用awkmatch函数来匹配正则表达式^TIME\[[0-9]+\.[0-9]+ms\][[:space:]]+-\([0-9]+\)-\.+将捕获我们实际上想要从行中删除的文本。然后打印除 OP 实际需要的匹配文本之外的其余文本。

您可以使用:

s='TIME[32.468ms]  -(3)-............."TEXT I WANT TO KEEP"'
sed -E 's/^TIME\[[^]]*].*\.+//'

"TEXT I WANT TO KEEP"

您的 sed 可能不支持 \s 正则表达式扩展。

在 BRE 语法中(这是 sed 开箱即用的内容),您不会在圆括号中使用反斜杠 - 这样做会将它们变成不匹配自身的正则表达式元字符,这有点不直观。此外,+ 只是 BRE 中的一个常规字符,而不是重复运算符(尽管您可以通过类似的反斜杠将其变成一个:\+)。

您可以尝试添加一个 -E 选项以从 BRE 语法切换到可能更熟悉的 ERE 语法,但这仍然不会启用 Perl 正则表达式扩展,它们也不是 ERE 语法的一部分。

sed 's/^TIME\[[^][]*\][[:space:]][[:space:]]-(3)-\.*//' myfile.txt

应该可以合理地工作 POSIX sed。 (还要注意减号不需要反斜杠转义,尽管这样做本身是无害的 此外,我加强了方括号的正则表达式,以防止 " match anything" regex you had .* from "escaping" past the closing square bracket. 更详细地说, [^][] 是一个否定字符 class 匹配任何不是(a换行符或) ][; 它们必须按此顺序准确指定以避免字符 class 定义中的歧义。最后,还要注意整个 sed 脚本通常应该用单引号引起来,除非您有特殊原因需要使用不同的引号。)

如果你有 sed -Esed -r 你可以使用 + 而不是 * 但这会使整个正则表达式复杂化,所以我不会在这里建议.

这个 awk 使用它的 sub() 函数:

awk 'sub(/^TIME[[][^]]*].*\.+/,"")' file
"TEXT I WANT TO KEEP"
  • 如果有替换,sub() returns true.
$ cut -d'"' -f2 file
TEXT I WANT TO KEEP

更简单的 sed:

sed 's/^[^"]*//' myfile.txt

如果“您要保留的文本”总是被这样的引号包围,并且只有它们在以“TIME...”开头的行中有引号,那么:

sed -n '/^TIME/p' file | awk -F'"' '{print }'

应该获取以“TIME...”开头的行并在引号内打印文本。

谢谢大家的帮助。 到最后,我找到了让它工作的方法:

echo 'TIME[32.468ms] -(3)-.............TEXT I WANT TO KEEP' | grep TIME | sed -r 's/^TIME\[[0-9]+\.[0-9]+ms\]\s\s-\(3\)-\.+//'

更一般地说,

grep TIME myfile.txt | sed -r ‘s/^TIME\[[0-9]+\.[0-9]+ms\]\s\s-\(3\)-\.+//’ 干杯, 佩德罗