【问题标题】:Read a pariticular section of list seperated by a delimiter into an array using shell script使用 shell 脚本将由分隔符分隔的列表的特定部分读入数组
【发布时间】:2017-06-28 20:17:15
【问题描述】:

我有一个以以下模式输出的命令

red
yellow
blue
green
--------
black
brown
pink

我想将“----”之前的列表读入一个数组,另一半读入另一个数组。

我知道这可以使用循环来完成。但我也认为这可以通过使用 SED 或 AWK 非常优雅地完成,问题是我不知道如何。我真的很感激这方面的任何帮助。我非常有信心这是可能的,但如果我错了或者有更好/更聪明的方法,请告诉我。

【问题讨论】:

  • 发布您的尝试以及您被阻止的位置。
  • 这也不是一个好方法,只有当你没有其他方法可以用你的原始命令来控制它时,才能像这样发布处理命令输出。
  • 我想了解更多关于这个问题的起源。你的实际用例是什么?我们能否得到一些确认(一旦你提出一个真正的问题)它不是XY problem
  • 我了解到您想创建一个 Bash 数组。除了读取它们的输出之外,您不能使用 awksed 创建 Bash 数组。如果你想将它们的输出分成两个数组,你仍然需要逐行读取它们的输出来检测你的分隔线,不管你打算如何创建数组。您的最佳解决方案可能会涉及某种循环或逐行解析。
  • 我需要限定我之前的评论:您可以通过两次读取输入来实现您想要的,并在第一次运行时使用 sed/awk 返回分隔符之前的行,并且第二次运行分隔符后的行,并执行两个单独的分配。

标签: bash shell awk sed ksh


【解决方案1】:

首先将整个列表读入一个数组。

readarray -t tmp < <(yourCommand)

然后搜索分隔符。

for ((i=0; i<${#tmp[@]}; i++)); do
    if [[ ${tmp[i]} == "--------" ]]; then
        break
    fi
done

然后使用子字符串扩展将数组分成两部分。请注意,如果没有找到分隔符,每个元素都将进入one,而two 则为空。

one=("${tmp[@]:0:i}")
two=("${tmp[@]:i+1}")

【讨论】:

    【解决方案2】:

    你可以试试这个吗?

    awk 'BEGIN {RS="" } {s=$i" "s } END { split(s,a,"--------"); print a [1],a[2]  } ' d
    
    red
    yellow
    blue
    green
    
    black
    brown
    pink
    

    a[1] 是顶部。 a[2] 是底部。

    【讨论】:

      【解决方案3】:

      此解决方案将逐行读取直到分隔符,将每一行附加到第一个数组,并使用一个命令创建第二个数组。

      #!/bin/bash
      declare -a array1=()
      while IFS= read -r line ; do
        [[ $line != "--------" ]] || break
        array1+=("$line")
      done
      readarray -t array2
      

      它需要在标准输入中接收其输入。将其放入脚本(例如 split_arrays)中,使其可执行,然后像这样调用它:

      ./split_arrays < <(command)
      

      或者:

      ./split_arrays <data_file
      

      【讨论】:

        【解决方案4】:

        我正在寻找一个更像这样的答案:

        $cat txt
        red
        yellow
        blue
        green
        --------
        black
        brown
        pink
        

        然后:

        array=$(cat txt | awk '{ if ($1~/----/) exit; else {print $1}}')
        echo $array
        
        red
        yellow
        blue
        green
        

        【讨论】:

          【解决方案5】:

          您实际上不需要任何类型的循环来处理文件。 这两个命令可以解决问题:

          sed -n '1,/-----/!p' a.txt #Will exclude 1st line up to pattern, excluding also the line with pattern = last part of your file
          sed -n '/-----/,$!p' a.txt #Will exclude pattern line up to last line excluding also the line with pattern = first part of your file
          

          然后您可以使用 readarray 技术将它们分配给不同的数组:

          readarray -t first < <(sed -n '/-----/,$!p' a.txt)
          readarray -t second < <(sed -n '1,/-----/!p' a.txt)    
          

          【讨论】:

            【解决方案6】:

            如果你的文件是这样的

            red
            yellow
            blue
            green
            --------
            black
            brown
            pink  
            

            那么你可以:

             $ array=$(cat file | grep -v - | tr '\n' ' ')
             $
             $ echo $array
             $ red yellow blue green black brown pink
             $
             $ echo ${array:0:21}
             $ red yellow blue green
             $
             $ echo ${array:22:-1}
             $ black brown pink
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-03-05
              相关资源
              最近更新 更多