循环匹配文本文件中的字符串

时间:2017-04-12 16:28:02

标签: bash loops

如何使用字符串“BUILD#”循环,并且只使用bash脚本打印具有以下字符串“http://”的行?  或者我们怎样才能把所有东西都用在字符串“BUILD”之间 input.txt中

BUILD #1
http://a
b
http://c

BUILD #2
http://d
http://c
http://g


BUILD #3
g
http://h
http://f
e
http://t

期望的输出

编辑注释:正如接受了什么答案所证明的那样,问题结果是 关于生成过滤的输出,但是要以一种了解封闭的构建上下文的方式有选择地处理行,  如前面BUILD #<n>行所暗示的那样。

BUILD #1 (loop)
http://a
http://c
add another loop to do something with http://

BUILD #2 (loop)
http://d
http://c
http://g
add another loop to do something with http://

BUILD #3 (loop)
http://h
http://f
http://t
add another loop to do something with http://

input.txt包含合并请求列表。

BUILD #1
take the link (integrate)
take the link (integrate)
kick of a build (build command)
BUILD #2 
take the link (integrate)
take the link (integrate)
take the link (integrate)
kick of a build (build command)
and so on 

2 个答案:

答案 0 :(得分:3)

你可以像这样循环:

while read -r; do
   # if current line starts with BUILD then set a variable build with build #
   [[ $REPLY == BUILD* ]] && build="${REPLY#BUILD }" && continue

   # if current line starts with http:// then execute a command using build # & link
   [[ $REPLY == http://* ]] && printf "Build: %s -> Link: %s\n" "$build" "$REPLY"
done < input.txt

Build: #1 -> Link: http://a
Build: #1 -> Link: http://c
Build: #2 -> Link: http://d
Build: #2 -> Link: http://c
Build: #2 -> Link: http://g
Build: #3 -> Link: http://h
Build: #3 -> Link: http://f
Build: #3 -> Link: http://t

您可以将printf更改为您想要的任何其他命令。

答案 1 :(得分:1)

anubhava's helpful answer向您展示如何按顺序迭代行,记录当前构建号,因为每个构建特定的行块都被输入。

这是一个解决方案,用于处理行中的 build by build 行,因此您可以根据需要应用构建级操作。

所有块都是按顺序处理的,但是不难以使解决方案适应仅按数字定位的特定构建。

#!/bin/bash

buildNum= urls=() finalIteration=0
while IFS= read -r line || { finalIteration=1; true; }; do
   # A new build block is starting or EOF was reached.
  if [[ $line =~ ^'BUILD #'([0-9]+) || $finalIteration -eq 1 ]]; then
    if [[ $buildNum ]]; then # Process the previous block.
      echo "Processing build #$buildNum..."
      # Process all URLs.
      i=0
      for url in "${urls[@]}"; do
        echo "Url #$((++i)): $url"
      done
      # Add further per-build processing here...
    fi    
    (( finalIteration )) && break # Exit the loop, if EOF reached.
    # Save this block's build number.
    buildNum=${BASH_REMATCH[1]}
    urls=() # Reset the array of URLs.
  # Collect the lines of interest in array ${url[@]}, for later processing.
  elif [[ $line =~ ^http:// ]]; then
    urls+=( "$line" )
  fi
done < input.txt