bash 中的 xargs sed 和命令替换
xargs sed and command substitution in bash
我正在尝试将 xargs 字符串替换传递到替换内的 sed 替换中,这是无效代码。
CALCINT=$CALCINT$(seq $CALCLINES | xargs -Iz echo $CALCINT' -F "invoiceid'z'="'$(sed -n '/invoiceid'z'/s/.*name="invoiceid'z'"\s\+value="\([^"]\+\).*//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="\([^"]\+\).*//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=\"\([^\"]\+\).*//p" output.txt > output2.txt
done
output2.txt 什么都不包含
感谢@janos 的回复,让我把事情搞清楚了,但退后一步让我明白,这里问题的根源是我正在努力获取发票 ID。它是动态生成的 HTML "....name="invoiceid7" value="556"..." 所以在我可以 grep 的那些特定标签中没有任何一致的东西,这就是为什么我正在计算另一个一致的标签然后尝试使用变量 sed 基本上推断标签名称然后提取值。
安..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="\([^"]\+\).*//p' output.txt)'"'
done
请通读下面对解决方案的评论,有一种更简洁的方法可以做到这一点。
您当前的方法行不通,特别是这部分:
... | xargs -Iz echo -F "invoiceid'z'="$(sed ...)"
问题是 $(sed ...)
在执行 xargs
期间不会为输入中的每一行求值。
shell 将计算一次, 在 它实际运行 xargs
之前。
您需要输入的动态值。
您可以采用不同的方法来完成这项工作:
- 提取发票 ID。例如,编写一个
grep
或 sed
管道,只生成发票 ID 列表 作为输出
- 将发票列表转换为您需要的
-F "invoiceidNUM=..."
形式
第二步,Awk可以实用。脚本可能是这样的:
curl -b mycookiefile -c mycookiefile http://localhost/calcint.php > output.txt
args=$(sed ... output.txt | awk '{ print "-F \"invoice" NR "=" [=11=] "\"" }')
echo $args
例如,如果 sed
步骤生成 2342、456456、78987,则输出将为:
-F "invoice1=2342" -F "invoice2=456456" -F "invoice3=78987"
我正在尝试将 xargs 字符串替换传递到替换内的 sed 替换中,这是无效代码。
CALCINT=$CALCINT$(seq $CALCLINES | xargs -Iz echo $CALCINT' -F "invoiceid'z'="'$(sed -n '/invoiceid'z'/s/.*name="invoiceid'z'"\s\+value="\([^"]\+\).*//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="\([^"]\+\).*//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=\"\([^\"]\+\).*//p" output.txt > output2.txt
done
output2.txt 什么都不包含
感谢@janos 的回复,让我把事情搞清楚了,但退后一步让我明白,这里问题的根源是我正在努力获取发票 ID。它是动态生成的 HTML "....name="invoiceid7" value="556"..." 所以在我可以 grep 的那些特定标签中没有任何一致的东西,这就是为什么我正在计算另一个一致的标签然后尝试使用变量 sed 基本上推断标签名称然后提取值。
安..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="\([^"]\+\).*//p' output.txt)'"'
done
请通读下面对解决方案的评论,有一种更简洁的方法可以做到这一点。
您当前的方法行不通,特别是这部分:
... | xargs -Iz echo -F "invoiceid'z'="$(sed ...)"
问题是 $(sed ...)
在执行 xargs
期间不会为输入中的每一行求值。
shell 将计算一次, 在 它实际运行 xargs
之前。
您需要输入的动态值。
您可以采用不同的方法来完成这项工作:
- 提取发票 ID。例如,编写一个
grep
或sed
管道,只生成发票 ID 列表 作为输出
- 将发票列表转换为您需要的
-F "invoiceidNUM=..."
形式
第二步,Awk可以实用。脚本可能是这样的:
curl -b mycookiefile -c mycookiefile http://localhost/calcint.php > output.txt
args=$(sed ... output.txt | awk '{ print "-F \"invoice" NR "=" [=11=] "\"" }')
echo $args
例如,如果 sed
步骤生成 2342、456456、78987,则输出将为:
-F "invoice1=2342" -F "invoice2=456456" -F "invoice3=78987"