如何使用 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
解释:使用awk
的match
函数来匹配正则表达式^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 -E
或 sed -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\)-\.+//’
干杯,
佩德罗
我有一个文本文件,其中写入了以下模式:
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
解释:使用awk
的match
函数来匹配正则表达式^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 -E
或 sed -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\)-\.+//’
干杯,
佩德罗