如何使用sed-awk-gawk显示匹配的字符串
我有一个名为'res'的文件,在一行字符串中包含29374个字符的http数据。在它里面,有几个http链接,但我只想显示那些以“/idnnnnn”结尾的链接,其中N是一个数字。事实上,我只对字符串“idnnnnnnn”感兴趣。 我试过:如何使用sed-awk-gawk显示匹配的字符串,sed,Sed,我有一个名为'res'的文件,在一行字符串中包含29374个字符的http数据。在它里面,有几个http链接,但我只想显示那些以“/idnnnnn”结尾的链接,其中N是一个数字。事实上,我只对字符串“idnnnnnnn”感兴趣。 我试过: cat res | sed -n '0,/.*\(id[0-9]*\).*/s//\1/p' 但我得到了整个文件。 你知道怎么做吗 cat res | perl -ne 'chomp; print "$1\n" if m/\/(id\d*)/' 应该有用。
cat res | sed -n '0,/.*\(id[0-9]*\).*/s//\1/p'
但我得到了整个文件。
你知道怎么做吗
cat res | perl -ne 'chomp; print "$1\n" if m/\/(id\d*)/'
应该有用。假设正好是9位数字;这就是上面的{9}
。您可以匹配8或9({8,9}
),8或更多({8,}
),最多匹配9({0,9}
),等等
此工作模式的示例:
$ echo -n 'junk jumk http://foo/id231313 junk lalala http://bar/id23123 asda' | perl -n -E 'say $1 while m!id(\d{0,9})!g'
231313
23123
当然是0到9的变体
如果您使用的是5.10版之前的perl,请使用-e
而不是-e
,打印“$1\n”
而不是说$1
工作原理
首先是Perl的两个命令行参数-n
告诉Perl从命令行上给出的标准输入或文件中逐行读取输入,并将$\uu
设置为每行$\uU7
是perl对很多事情的默认目标,包括正则表达式匹配-E
仅仅告诉Perl下一个参数是Perl一行程序,使用了新的语言特性(与不使用5.10扩展的-E
相比)
所以,看一行:say
意味着打印出一些值,后跟一个换行符$1
是第一个正则表达式捕获(捕获是通过正则表达式中的括号进行的)while
是一种循环结构,您可能很熟悉m
是匹配运算符,代码>之后是正则表达式分隔符(通常,您会在这里看到/
,但由于模式包含/
,因此使用其他内容更容易,因此您不必将/
转义为\/
)/id(\d{9})
是要匹配的正则表达式。请记住,分隔符是
,因此/
不是特殊的,它只匹配一个文本/
。括号构成捕获组,因此,$1
将是数字。
是分隔符,后跟g
,表示尽可能多次匹配(而不是一次)。这就是为什么它会拾取行中的所有URL,而不仅仅是第一个URL。只要存在匹配项,m
操作符将返回一个真值,因此循环将继续(并运行该例如$1
,打印出匹配项)
双色解
我认为这是一种只使用sed的方法。更复杂
echo 'junk jumk http://foo/id231313 junk lalala http://bar/id23123 asda' | \
sed 's!http://!\nhttp://!g' | \
sed 's!^.*/id\([0-9]*\).*$!\1!'
问题是sed、grep和awk是在线工作的,而您只有一条线。所以,你可能需要把东西分开,这样你就有了不止一行,然后你就可以让普通的工具工作了
tr ':' '\012' < res |
sed -n 's%.*/\(id[0-9][0-9]*\).*%\1%p'
tr':''\012'
这利用了包含冒号的URL,并将冒号映射到带有tr
的换行符,然后使用sed
拾取斜杠,后跟id
和一个或多个数字,后跟任何内容,并打印出id和数字字符串(仅限)。由于这些仅出现在URL中,因此它们每行仅出现一个,并且也相对靠近行的开头。这里有一个解决方案,只需调用一次sed
:
sed -n 's| |\n|g;/^http/{s|http://[^/]*/id\([0-9]*\)|\1|;P};D' inputfile
说明:
s | |\n | g代码>-分而治之
/^http/{
-如果模式空间以“http”开头
s| http://[^/]*/id\([0-9]*\)\1 |
-捕获id
P
-打印第一个换行符前面的字符串
}代码>-如果结束,则结束
D
-删除第一个换行符前面的字符串,无论它是否包含“http”
编辑:
此版本使用相同的技术,但更具选择性
sed -n 's|http://|\n&|g;/^\n*http/{s|\n*http://[^/]*/id\([0-9]*\)|\1\n|;P};D' inputfile
这将显示整行(“问题中的29374字符http数据一行字符串”)谢谢,但我什么也没有得到。你是说每行都有一个带有多个链接的html文本吗?文件中只有一行!谢谢Zimbabao,它可以工作,但它只显示了一个事件,那里有6个,这很酷!两件事:1)我不太习惯perl语法,请您解释一下好吗?2) 有可能使用awk gawk sed吗?@Morphy:如果你经常这样做文本处理,perl就是这项工作的工具。我将补充一个解释,说明它是如何工作的。Sed肯定能做到,但我不确定如何做到(最坏的情况是,你可能会用一个Sed分割行,然后再匹配一个Sed)。@Morphy:我也为你找到了一个Sed唯一的解决方案。要复杂得多,但它似乎可以工作。@Morphy:然后您必须更改regexp以匹配您想要的任何内容。e、 例如,您可以(未经测试)(http://blah\.com/kdivw/id\d+
(+
是{1,}
:一个或多个)再次感谢,但我只知道域blah.com
,我如何匹配.com
到id12345678
?几乎!返回:id257593647 id257593647 id257593647�抱歉,丹尼斯,这会返回http equiv=“content type”
sed -n 's|http://|\n&|g;/^\n*http/{s|\n*http://[^/]*/id\([0-9]*\)|\1\n|;P};D' inputfile