首页 > 解决方案 > 将 awk 找到的每个事件存储到一个数组中

问题描述

我之前的问题被标记为“重复”,我被指向thisthis。这些线程上提供的解决方案根本不能解决这个问题。

file.txt 的内容:

Some line of text 0
Some line of text 1
Some line of text 2
PATTERN1
Some line of text 3
Some line of text 4
Some line of text 5
PATTERN2
Some line of text 6
Some line of text 7
Some line of text 8
PATTERN1
Some line of text 9
Some line of text 10
Some line of text 11
PATTERN2
Some line of text 12
Some line of text 13
Some line of text 14

我需要在两者之间提取“PATTERN1”和“PATTERN2”+ 行,下面的命令可以完美地做到这一点:

awk '/PATTERN1 /,/PATTERN2/' ./file.txt

输出:

PATTERN1
Some line of text 3
Some line of text 4
Some line of text 5
PATTERN2

PATTERN1
Some line of text 9
Some line of text 10
Some line of text 11
PATTERN2

但现在我正在尝试创建一个 bash 脚本:

  1. 使用 awk 查找 PATTERN1 和 PATTERN2 之间的线
  2. 将每次出现的 PATTERN1 + 行在 + PATTERN2 之间存储在一个数组中
  3. 执行 1 和 2 直到文件结束。

澄清。表示将以下行存储在引号内:

"PATTERN1
Some line of text 3
Some line of text 4
Some line of text 5
PATTERN2"

array[0]

并将以下行存储在引号内:

"PATTERN1
Some line of text 9
Some line of text 10
Some line of text 11
PATTERN2"

array[1]

依此类推......如果 PATTERN1 和 PATTERN2 出现更多

我目前拥有的:

#!/bin/bash
var0=`cat ./file.txt`
mapfile -t thearray < <(echo "$var0" | awk '/PATTERN1 /,/PATTERN2/')

以上不起作用。
并且我尽可能不想使用 mapfile,因为该脚本可能在不支持它的系统上执行。

基于提供的链接:

myvar=$(cat ./file.txt)
myarray=($(echo "$var0" | awk '/PATTERN1 /,/PATTERN2/')) 

但是当我这样做时echo ${myarray[1]}

我得到一个空白的答复。

当我这样做时echo ${myarray[0]}

我得到:

PATTERN1
Some line of text 3
Some line of text 4
Some line of text 5
PATTERN2

PATTERN1
Some line of text 9
Some line of text 10
Some line of text 11
PATTERN2

当我做回声时我期望什么${myarray[0]}

PATTERN1
Some line of text 3
Some line of text 4
Some line of text 5
PATTERN2

当我做的时候我期望什么echo ${myarray[1]}

PATTERN1
Some line of text 9
Some line of text 10
Some line of text 11
PATTERN2

任何帮助都会很棒。

标签: arraysbashshellawk

解决方案


一个简单的实现bash可能是这样的:

#!/bin/bash

beginpat='PATTERN1'
endpat='PATTERN2'

array=()
n=-1
inpatterns=
while read -r; do
    if [[ ! $inpatterns && $REPLY = $beginpat ]]; then
        array[++n]=$REPLY
        inpatterns=1
    elif [[ $inpatterns ]]; then
        array[n]+=$'\n'$REPLY
        if [[ $REPLY = $endpat ]]; then
            inpatterns=
        fi
    fi
done

# Report captured lines
for ((i = 0; i <= n; ++i)); do
    printf "=== array[%d] ===\n%s\n\n" $i "${array[i]}"
done

运行为./script < file. awk不需要使用,但脚本也可以在awk输出上正常工作。


推荐阅读