我有一个名为raw.txt
的文本文件,其中包含以下内容:
T DOTTY CRONO 52/50 53/40 54/30 55/20 RESNO NETKI
U CYMON DENDU 51/50 52/40 53/30 54/20 DOGAL BEXET
V YQX KOBEV 50/50 51/40 52/30 53/20 MALOT GISTI
W VIXUN LOGSU 49/50 50/40 51/30 52/20 LIMRI XETBO
X YYT NOVEP 48/50 49/40 50/30 51/20 DINIM ELSOX
Y DOVEY 42/60 44/50 47/40 49/30 50/20 SOMAX ATSUR
Z SOORY 43/50 46/40 48/30 49/20 BEDRA NERTU
A DINIM 51/20 52/30 50/40 47/50 RONPO COLOR
B SOMAX 50/20 51/30 49/40 46/50 URTAK BANCS
C BEDRA 49/20 50/30 48/40 45/50 VODOR RAFIN
D ETIKI 48/15 48/20 49/30 47/40 44/50 BOBTU JAROM
E 46/40 43/50 42/60 DOVEY
F 45/40 42/50 41/60 JOBOC
G 43/40 41/50 40/60 SLATN
我正在把它读成一个数组:
while read line; do
set $line
IFS=' ' read -a array <<< "$line"
done < raw.txt
我正在尝试用[A-Z]{5}
结果替换所有出现的curl
,其中[A-Z]{5}
的匹配作为变量提供给curl
调用。
要替换的第一场比赛是DOTTY
。该调用与curl -s http://example.com/api_call/DOTTY
类似,结果类似-55.5833 50.6333
,应该替换数组中的DOTTY
。
到目前为止,我无法正确匹配所需的字符串并将匹配送入curl。
非常感谢您的帮助。
一切顺利, 克里斯
编辑:
解决方案
基于@Kevin广泛回答的工作解决方案和@Floris暗示卷曲结果中可能的回车。确实如此。谢谢!结合我身边的一些修修补补,我现在可以开始工作了。
#!/bin/bash
while read line; do
set $line
IFS=' ' read -a array <<< "$line"
i=0
for str in ${array[@]}; do
if [[ "$str" =~ [A-Z]{5} ]]; then
curl_tmp=$(curl -s http://example.com/api_call/$str)
# cut off line break
curl=${curl_tmp/$'\r'}
# insert at given index
declare array[$i]="$curl"
fi
let i++
done
# write to file
for index in "${array[@]}"; do
echo $index
done >> $WORK_DIR/nats.txt
done < raw.txt
答案 0 :(得分:2)
除了添加匹配的部分之外,我没有改变你的脚本,因为它似乎是你需要帮助的:
#!/bin/bash
while read line; do
set $line
IFS=' ' read -a array <<< "$line"
for str in ${array[@]}; do
if [[ "$str" =~ [A-Z]{5} ]]; then
echo curl "http://example.com/api_call/$str"
fi
done
done < raw.txt
编辑:在您提供的URI中的变量的url示例中添加。通过将其更改为do_something“$(curl ...)”
,您可以使用获取的输出执行任何操作EDIT2:既然你想要维护你从每一行创建的bash数组,那么这个怎么样:
关于数组,我不太擅长bash,所以我希望有人能给我打电话,但这应该可行。
我在那里留下了一些回声,所以你可以看到它在做什么。 shift
命令用于在正则表达式匹配时从当前位置推送数组索引。用于保存curl输出的tmp变量可能会得到改善,但这应该让你开始,我希望。
removed temporarily to avoid confusion
EDIT3:哎呀上面没有实际工作。我的错。让我再试一次。
EDIT4:
#!/bin/bash
while read line; do
set $line
IFS=' ' read -a array <<< "$line"
i=0
# echo ${array[@]} below is just so you can see it before processing. You can remove this
echo "Array before processing: ${array[@]}"
for str in ${array[@]}; do
if [[ "$str" =~ [A-Z]{5} ]]; then
# replace the echo command below with your curl command
# ie - curl="$(curl http://example.com/api_call/$str)"
curl="$(echo 1234 -1234)"
if [[ "$flag" = "1" ]]; then
array=( ${adjustedArray[@]} )
push=$(( $push + 2 ));
let i++
else
push=1
fi
adjustedArray=( ${array[@]:0:$i} ${curl[@]} ${array[@]:$(( $i + $push)):${#array[@]}} )
#echo "DEBUG adjustedArray in loop: ${adjustedArray[@]}"
flag=1;
fi
let i++
done
unset flag
echo "final: ${adjustedArray[@]}"
# do further processing here
done < raw.txt
我知道有一种更聪明的方法可以做到这一点,但我们正在进入bash的地区,我不太适合提供建议。以上应该有效,但我希望有人可以做得更好。
希望它有所帮助,无论如何
ps - 除非你真的需要,否则你可能不应该使用shell脚本。 Perl,php或python会使代码简单易读
答案 1 :(得分:2)
因为我第一次误读了:
如何使用sed?
sed "s/\([A-Z]\{5\}\)/$(echo curl http:\\/\\/example.com\\/api_call\\/\\1)/g" /tmp/raw.txt
试试,然后尝试删除回声。我不是百分之百,因为我不能在真实域上运行它
编辑:就这样,我很清楚,回声就在那里,所以你可以看到它将如何去除回声
答案 2 :(得分:2)
创建文件cmatch
:
#!/bin/bash
while read line
do
echo $line
a=`echo $line | egrep -o '\b[A-Z]{5}\b'`
for v in $a
do
echo "doing curl to replace $v in $line"
r=`curl -s http://example.com/api_call/$v`
r1=`echo $r | xargs echo`
line=`echo $line | sed 's/'$v'/'$r1'/'`
done
done
然后用
调用它chmod 755 cmatch
./cmatch < inputfile.txt > outputfile.txt
它会按照您的要求进行操作
注意:
\b
之前和之后[A-Z]{5}
确保ABCDEFG
(不是五个字母的单词)不匹配。egrep -o
生成一系列匹配curl
调用curl
的结果分配给中间变量编辑刚看到有关数组的评论。如果你想进行进一步的操作,我建议把这个脚本的输出转换成数组...
更多编辑如果您的curl
命令返回多行字符串(可以解释您看到的错误),则可以使用我在脚本中引入的新行来删除换行符(基本上将所有参数串在一起):
echo $r | xargs echo
一次一行调用echo
作为参数,没有回车符。这是摆脱回车的有趣方式。
答案 3 :(得分:0)
#!/bin/bash
while read line;do
set -- $line
echo "second parm is $2"
echo "do your curl here"
done < afile.txt