Bash:用curl结果替换数组值

时间:2014-01-14 00:20:41

标签: regex bash sed

我有一个名为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

4 个答案:

答案 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