1

我正在尝试编写一个脚本以自动登录到 Drupal 网站以使其进入维护模式。这是我到目前为止所拥有的,grep 给了我我想要的行。

curl http://www.drupalwebsite.org/?q=user | grep '<input type="hidden" name="form_build_id" id="form-[a-zA-Z0-9]*" value="form-[a-zA-Z0-9]*"  />'

现在我是一个 Linux 新手,我正在使用 Cygwin 和 BASH。然后我将如何管道输出并使用命令从 grep 生成的输出中获取 id 属性的值?稍后我将使用此子字符串执行另一个 curl 请求以实际提交登录。

我正在考虑使用 expr,但我真的不明白我会如何告诉 expr“哦,嘿,我希望你以这种方式操作这个标准输入数据”。似乎我能做到这一点的唯一方法是将grep输出保存在一个变量中,然后将该变量提供给expr。

4

2 回答 2

1

您可以grep再次使用该-o选项。可能连续两个greps 也过滤掉周围的id="..."部分。

   -o, --only-matching
          Print only the matched (non-empty) parts  of  a  matching  line,
          with each such part on a separate output line.
于 2012-01-28T23:57:49.663 回答
1

用于sed修剪从grep, 即得到的结果。

编辑:添加 myID 变量,使用您喜欢的任何名称。

myID=$( 
  curl http://www.drupalwebsite.org/?q=user \
  | grep '<input type="hidden" name="form_build_id" id="form-[a-zA-Z0-9]*" value="form-[a-zA-Z0-9]*"  />' \
  | sed 's/^.* id="//;s/" value=.*$//'
)


#use ${myID} later in script
printf "myID=${myID}\n"

第一部分删除字符串的“前”部分,直到 . id=",而第二部分删除每个" value= .....

sed请注意,您可以通过用“;”分隔多个子替换操作来将它们链接在一起。

edit2 另外,一旦你使用了 sed,就没有理由使用 grep,试试这个:

myID=$( 
  curl http://www.drupalwebsite.org/?q=user \
  | sed -n '\@<input type="hidden" name="form_build_id" id="form-[a-zA-Z0-9]*" value="form-[a-zA-Z0-9]*"  />@{
       s\@^.* id="@@
       s\@" value=.*$@@p
   }'
)

(养成删除不必要进程的好习惯。在这种情况下可能无关紧要,但是如果您编写的代码将在一个小时内执行 1000 次,那么当您不这样做时,就会有一个额外的 grep不需要它是创建 1000 个不需要创建的额外进程。)

您可能必须转义 '< 和 >' 字符,例如 '\< >' 或,最坏的情况是 '[<] [>]'。

我现在使用 '@' 作为 reg-ex 替换分隔符,以避免必须转义 srch-target 字符串中的任何 '/' 字符。我在整个示例中继续使用它,只是为了保持一致。对于某些 sed,您已经告诉他们您正在使用非标准分隔符,因此每个 sed 代码块前面的前导 \@ 。

-n 表示“不默认打印每一行输入”,因此,我们必须在末尾添加“p”,这意味着打印当前缓冲区。

最后,我不确定您的正则表达式,尤其是-[a-zA-Z0-9]*,这意味着零个或多个前一个字符(或本例中的字符类)。通常,想要至少一个字母数字的人会使用-[a-zA-Z0-9][a-zA-Z0-9]*, yes OR [[:alnum:]][[:alnum:]]*,但我不太了解您的数据,无法确定。

我希望这有帮助。

于 2012-01-29T00:14:07.303 回答