【问题标题】:Bash Issue : sed: -e expression #1, char 16: unknown option to `s' [duplicate]Bash问题:sed:-e表达式#1,char 16:`s'的未知选项[重复]
【发布时间】:2018-03-11 16:07:15
【问题描述】:

我正在尝试传递 curl 请求和来自响应正文,我正在尝试 grep 关键字“硬币”。如果 "coin" 单词匹配,我需要获取 "0" 或 "1" 输入 URL 作为 prefix (逗号 delineated)。

$for i in $(cat small);do curl -i -H "Accept: application/json" $i | grep "coin";echo $? | sed "s/^\(.\)/$i,\1/";done

#cat small

http://cuevana0.tv/
https://www.1111data.com/

我将输入作为前缀添加到结果“sed”s/^(.)/$i,\1/"。

但是我遇到了错误

$ for i in $(cat small);do curl -i -H "Accept: application/json" $i | grep "coin";echo $? | sed "s/^\(.\)/$i,\1/";done
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  633k    0  633k    0     0   909k      0 --:--:-- --:--:-- --:--:--  908k
    <script src="https://coin-hive.com/lib/coinhive.min.js"></script>
sed: -e expression #1, char 16: unknown option to `s'

关于如何解决这个问题的任何建议?虽然上述不是一个好的做法,但它会及时帮助我。

预期结果:

http://cuevana0.tv/,0

【问题讨论】:

  • 您需要一个复合语句来运行多个命令,即.. | { grep "coin";echo $?; } | ..,即使使用它,它也是非常糟糕的编码实践序列。向我们提出您明确希望对样本 i/p 和预期 o/p 做什么的要求
  • 谢谢@Inian。我同意并且我已经更新了上面的问题。

标签: bash shell curl sed


【解决方案1】:

我认为在bash 中进行编码的正确方法是避免无用的cat 用法和正确使用工具(grep,返回代码)

#!/usr/local/env bash

while IFS= read -r url; do
    if curl -i -H "Accept: application/json" "$url" 2>&1 | grep -q "coin"; then
        printf "%s,0\n" "$url" 
    else
        printf "%s,1\n" "$url" 
    fi
done < urlFile

以上代码使用正确的方式

  1. 使用输入文件重定向并使用while 循环和read 命令循环文件(避免在有空格时分行)
  2. 通过将搜索输出-q 抑制到控制台,直接在if 子句中使用grep 的返回码
  3. curlstdoutstderr 都传递给grep 以查找关键字。
  4. 对变量进行双引号,以免在出现空格时因分词而使它们分裂。

正如伟大的glenn-jackman 指出的那样,您可以将整个 if-else 子句替换为此

curl -i -H "Accept: application/json" "$url" 2>&1 | grep -q "coin"; printf "%s,%d\n" "$url" $?

意思是在管道后面打印grep的错误代码。

【讨论】:

  • curl -i -H "Accept: application/json" "$url" 2&gt;&amp;1 | grep -q "coin"; printf "%s,%d\n" "$url" $? 会有点干燥
  • @glennjackman 我同意这个想法,但我怀疑$? 可能不能保证在curl 失败时是1。我们需要将$? 更改为$(( $? != 0 )) 或类似内容,以保证在那里获得01 值。
【解决方案2】:

直接的问题是您在sed 表达式中使用“/”字符作为分隔符,但您要替换的字符串也包含“/”,因此sed 将其误认为是分隔符和变得非常困惑。例如,在 URL“http://cuevana0.tv/”上,您正在运行以下命令:

sed "s/^\(.\)/http://cuevana0.tv/,\1/"

...由于额外的“/”字符,sed 语法无效。您可以改用其他分隔符,例如 ... | sed "s@^\(.\)@$i,\1@"; ...(前提是您确定“@”永远不会出现在您的某个网址中)。

但是有一个更好的方法可以做到这一点。而不是echoing 状态,然后使用编辑添加 URL,只需使用 echo "$i,$?"

这里的另一件事是个坏主意:for i in $(cat small) 可能会遇到许多潜在问题,具体取决于文件可能包含的空格和/或通配符。一般来说,while read -r i; do ... done &lt;small 更容易预测。除了如果循环内的任何内容从标准输入读取(或可能从标准输入读取),您应该改用while read -r i &lt;&amp;3; do ... done 3&lt;small

猜你喜欢
  • 2013-03-08
  • 2021-02-07
  • 2014-04-06
  • 2020-11-25
  • 2018-04-25
  • 2022-12-28
  • 2020-11-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多