【问题标题】:Shell script - remove all before and afterShell 脚本 - 删除之前和之后的所有内容
【发布时间】:2021-02-13 04:29:15
【问题描述】:

如果链接头包含 rel=next.. 则查找下一个链接 获取链接标题可能会导致不同的字符串。我需要找到下一个链接。 例如

Link: <http://mygithub.com/api/v3/organizations/20/repos?page=1>; rel=prev, <http://mygithub.com/api/v3/organizations/20/repos?page=3>; rel=next, <http://mygithub.com/api/v3/organizations/20/repos?page=4>; rel=last, <http://mygithub.com/api/v3/organizations/20/repos?page=1>;

应该是http://mygithub.com/api/v3/organizations/20/repos?page=3

Link: <http://mygithub.com/api/v3/organizations/4/repos?page=2>; rel="next", <http://mygithub.com/api/v3/organizations/4/repos?page=2>; rel="last"

应该是http://mygithub.com/api/v3/organizations/4/repos?page=2

玩过 sed 和参数扩展 - 没那么有经验,所以卡住了 :)

【问题讨论】:

  • “Shell”意味着您需要与/bin/sh 兼容,或者它是否在 bash、ksh、zsh 或其他扩展 shell 中运行?如果你在一个支持本机正则表达式的 shell 中,你应该考虑使用它。
  • extract substring using regexp in plain bash 中使用BASH_REMATCH 查看答案。当您在每次调用时仅使用一行输入来运行 sed 时,通常最好避免使用它——启动每个副本都需要很长时间,即使它在运行后非常快。
  • @shellter 谢谢。一个问题..如何将值分配给shell脚本中的变量。例如我在变量名称 nextReposLink echo $nextReposLink 中有带有链接的字符串。 - 使用我的 github 链接打印字符串我想将命令的结果保存在一个新变量中...$nextReposLink | awk '{for (i=0; i&lt;=NF; i++){if ($i == "rel=next,"){print $(i-1);exit}}}' | sed -e 's/&lt;/ /' -e 's/&gt;;/ /' 类似的东西,但这给了我一个“错误的替换”x="${echo $nextReposLink | awk '{for (i=0; i&lt;=NF; i++){if ($i == \"rel=next,\"){print $(i-1);exit}}}'}"
  • @shellter 谢谢...你想回答这个问题吗? :)

标签: shell


【解决方案1】:

嗯 - 我将您的一个 URL 字符串放在一个文本文件中,并且能够通过两次剪切提取第一个 URL。

[root@oelinux2 ~]# cat test
Link: <http://mygithub.com/api/v3/organizations/20/repos?page=1>; rel=prev, <http://mygithub.com/api/v3/organizations/20/repos?page=3>; rel=next, <http://mygithub.com/api/v3/organizations/20/repos?page=4>; rel=last, <http://mygithub.com/api/v3/organizations/20/repos?page=1>;

然后使用剪切:

cat test | cut -d "<" -f2 | cut -d ">" -f1


[root@oelinux2 ~]# cat test | cut -d "<" -f2 | cut -d ">" -f1
http://mygithub.com/api/v3/organizations/20/repos?page=1

这是一个选项 - 如果您只是想获取字符串中的第一个 URL。基本上 - 这只是抓住两个分隔符“”

之间的内容

带剪切: -d 是“分隔符” -f 是你要获取的字段。

如果您想在该字符串中获取稍后的 URL,您可以更改字段 (-f #) 并查看您得到的内容:)

【讨论】:

  • 下一个链接不会总是在同一个位置。正如你所看到的,有时 prev 是第一位的。就像我必须找到字符串 'rel="next"' 然后从那里向后找到第一个 > 然后是
  • 哦,是的.. 看到这一点 - 也许 Charles Duffy 在回复您的 OP 时使用 Regex 可能是最好的.. 因为 cut 和 awk 非常依赖于使用位置字段。我相信您可以使用正确的正则表达式语句来完成它 - 但我不是真正的正则表达式专家..
【解决方案2】:

请注意,使用非 html 工具解析 HTML 会带来危险;你会看到这是可行的,并假设你总是可以摆脱它。当您应该学习如何使用 html-aware 工具时,您将花费数小时尝试使工作更复杂。不要说我们没有警告你(-;,但是

printf "<http://mygithub.com/api/v3/organizations/20/repos?page=1>; rel=prev, <http://mygithub.com/api/v3/organizations/20/repos?page=3>; rel=next, <http://mygithub.com/api/v3/organizations/20/repos?page=4>; rel=last, <http://mygithub.com/api/v3/organizations/20/repos?page=1>;\n" \
| awk -F" " '{
    for(i=1;i<=NF;i++){
       if ($i == "rel=next,") {
         gsub(/[<>]/,"",$(i-1);sub(/;$/,"",$(i-1))
         print $(i-1)
       }
    }
}'

产生所需的输出:

http://mygithub.com/api/v3/organizations/20/repos?page=3

要将脚本部分的输出保存到变量中,您需要包装代码以进行命令替换,在这种情况下

 nextReposLink=$( printf .... | awk '....' )
 #-------------^^--------------------------^

^ 指向的项目是命令替换的现代语法。 $( ... ) 内部的代码被执行,标准输出作为参数传递给调用命令行。 (命令替换的原始语法是/是 `cmds` 并且在简单的情况下工作相同 var=`cmds` 。您可以轻松嵌套现代 cmd 替换,而旧版本需要很多转义字符摆弄。如果可以的话,避免它。

请注意,sed 可以做的任何s/str/rep/ 都可以,awk 也可以做同样的事情,但需要使用sub(/regx/, "repl", "str")gsub(sameArgs) 函数。在这种特殊情况下,您可能需要像 \&lt;\&gt; 一样转义 &lt;&gt;

请务必始终使用 dbl-quote 引用变量,即echo "$nextReposLink"

IHTH

【讨论】:

    猜你喜欢
    • 2015-08-13
    • 2022-11-07
    • 1970-01-01
    • 2017-12-31
    • 2016-05-11
    • 1970-01-01
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多