【问题标题】:xargs sed and command substitution in bashbash 中的 xargs sed 和命令替换
【发布时间】:2017-12-05 09:44:45
【问题描述】:

我正在尝试将 xargs 字符串替换传递给替换中的 sed 替换,这是无效的代码。

CALCINT=$CALCINT$(seq $CALCLINES | xargs -Iz echo $CALCINT' -F "invoiceid'z'="'$(sed -n '/invoiceid'z'/s/.*name="invoiceid'z'"\s\+value="\([^"]\+\).*/\1/p' output.txt))

一切正常,直到第二次替换中的 sed。 'z' 应该是基于 $CALCLINES 变量的数字 1-20。我知道这与没有为 sed 正确转义有关,但我无法理解 sed 如何在这种情况下逃脱。

这是周围的代码行:

curl -b mycookiefile -c mycookiefile http://localhost/calcint.php > output.txt
CALCLINES=`grep -o 'class="addinterest"' output.txt | wc -l`
CALCINT=$CALCINT$(seq $CALCLINES | xargs -Iz echo $CALCINT' -F "invoiceid'z'="'$(sed -n '/invoiceid17/s/.*name="invoiceid17"\s\+value="\([^"]\+\).*/\1/p' output.txt))
echo $CALCINT

输出:(我现在得到的)

-F "invoiceid1=" -F "invoiceid2=" -F "invoiceid3=" -F "invoiceid4=" -F "invoiceid5=" -F "invoiceid6=" -F "invoiceid7=" -F "invoiceid8=" -F "invoiceid9=" -F "invoiceid10=" -F "invoiceid11=" -F "invoiceid12=" -F "invoiceid13=" -F "invoiceid14=" -F "invoiceid15=" -F "invoiceid16=" -F "invoiceid17=" -F "invoiceid18=" -F "invoiceid19=" -F "invoiceid20="

我希望看到的输出是这样的

-F "invoiceid1=2342" -F "invoiceid2=456456" -F "invoiceid3=78987" ...etc etc

--------------编辑---------- --

FWIW...这是 output.txt 和我尝试过的其他内容。

for i in $(seq -f "%02g" ${CALCLINES});do
sed -n "/interest$i/s/.*name=\"interest$i\"\s\+value=\"\([^\"]\+\).*/\1/p" output.txt > output2.txt
done

output2.txt 不包含任何内容

感谢@janos 回复以解决问题,但退后一步让我清楚地知道,这里问题的根源是我正在努力获取发票 ID。它是动态生成的 HTML "....name="invoiceid7" value="556"..." 所以在那些我可以 grep 的特定标签中没有任何一致的东西,这就是为什么我计算另一个标签是一致然后尝试使用变量 sed 基本上推断标签名称然后提取值。

Annd..output.txt https://pastebin.com/ewUaddVi

-----更新----- 工作解决方案

把 sed 塞进一个循环。请注意我必须如何使用 ' 来使用 sed 字符串中的变量。这在此处的其他地方都有很好的记录。 :)

for i in $(seq ${CALCLINES});do
e="interest"$i`
CALCINT=$CALCINT' -F "'$e'='
CALCINT=$CALCINT$(sed -n '/'$e'/s/.*name="'$e'"\s\+value="\([^"]\+\).*/\1/p' output.txt)'"'
done

请通读下面解决方案中的 cmets,有一种更简洁的方法。

【问题讨论】:

    标签: bash shell sed grep xargs


    【解决方案1】:

    你目前的方法行不通,特别是这部分:

    ... | xargs -Iz echo -F "invoiceid'z'="$(sed ...)"
    

    问题是$(sed ...) 在执行xargs 期间不会针对输入中的每一行进行评估。 shell 将评估一次,它实际运行xargs。 而且您需要输入中的动态值。

    您可以采用不同的方法来完成这项工作:

    1. 提取发票 ID。例如,编写一个 grepsed 管道,它只生成发票 ID 列表作为输出
    2. 将发票列表转换为您需要的-F "invoiceidNUM=..."表格

    对于第二步,Awk 可能是实用的。脚本可能是这样的:

    curl -b mycookiefile -c mycookiefile http://localhost/calcint.php > output.txt
    args=$(sed ... output.txt | awk '{ print "-F \"invoice" NR "=" $0 "\"" }')
    echo $args
    

    例如,如果sed 步骤产生 2342、456456、78987,那么输出将为:

    -F "invoice1=2342" -F "invoice2=456456" -F "invoice3=78987"
    

    【讨论】:

    • 明白这是有道理的,但我想问题的根源在于我正在努力获取发票 ID。它是动态生成的 HTML "....name="invoiceid7" value="556"..." 所以在那些我可以 grep 的特定标签中没有任何一致的东西,这就是为什么我计算另一个标签是一致然后尝试使用变量 sed 基本上推断标签名称然后提取值。
    • @Blinder 你不能只做grep -o invoiceid'[0-9]*' 吗?
    • 是的,但这只是我的一半。另外我不知道每次会有多少元素。如果他们能在数据库中完成工作会很好,这样我就可以使用 curl 传递发票 ID 列表来收取利息,但这一切都是在客户端完成的,所以我不得不砍掉 HTML。最后,我能够在这样的循环中让 sed 足够快乐: for i in $(seq ${CALCLINES});do e="interest"$i CALCINT=$CALCINT' -F "'$e'= ' CALCINT=$CALCINT$(sed -n '/'$e'/s/.*name="'$e'"\s\+value="([^"]\+).*/\1/ p' output.txt)'"' 完成
    • @Blinder 如果您共享一个示例输入和从中提取的所需 id 列表,我怀疑可以使用更简单的sed 来完成,而无需循环。但这值得它自己单独的问题。
    • 如果您(或其他任何人)喜欢冒险,上面的 pastebin 链接就是示例输入。目标是获取所有输入标签名称 interestX invoiceidX 和 curX 的值属性。 X 从 1 开始,并根据软件输出的任何内容趋于无穷大。仍在做这个项目,但这个问题已经解决了
    猜你喜欢
    • 1970-01-01
    • 2010-11-29
    • 1970-01-01
    • 2021-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    • 2013-09-28
    相关资源
    最近更新 更多