Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用sed-awk-gawk显示匹配的字符串_Sed - Fatal编程技术网

如何使用sed-awk-gawk显示匹配的字符串

如何使用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*)/' 应该有用。

我有一个名为'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*)/'
应该有用。假设正好是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�
sed -n 's|http://|\n&|g;/^\n*http/{s|\n*http://[^/]*/id\([0-9]*\)|\1\n|;P};D' inputfile