artemis
artemis

Reputation: 7241

Bash add regex values to an array

I am trying to write a bash script that will take in a file and look for all values matching a regular expression, and then add those to an array.

As a first step, I wrote a script that adds all lines in the log file to an array, and echoes them. Then, I tried editing that script to search for the regular expression in the log file, which is where I got a tremendous amount of errors.

What I am trying to do is grab the value inside the brackets of the log file. Some lines in the log file contain a syntax like [23423234 s] which is a time stamp. I want to grab the values (digits, space, and the "s") inside the brackets( but not the brackets!) and add those values to an array.

My initial script is below:

#!/bin/bash

echo "STARTING SCRIPT"

getArray(){
        array=()
        while IFS= read -r line
        do
                array+=("$line")
        done <"$1"
}

getArray "testlog.txt"
for e in "${array[@]}"
do
        echo "$e"
done

echo "DONE SCRIPT"

The log I am looking at looks like this:

[1542053213 s] Starting Program:
-----------------------------------------
[1542053213 s] PROGRAM ERROR
ERRHAND: 1033
ERRHAND: 233545
ERRHAND: 1
[1542053213 s] Program completed!

[1542053213 s] Config File complete. Stopping!

What I am aiming to do is do something with the following pseudocode:

For each line in file{
regex = [\d\ws]


    if line matches regex{
        add to array
    }
}

for each item in array{
    echo item
}

Currently, I have edited my script to look like below:

#!/bin/bash

echo "STARTING SCRIPT"

getArray(){
    array=()
    while IFS= read -r line
    do
        if [[$line =~ [\d\ws]; then
        array+=("$line");
        fi
    done <"$1"  
}

getArray "log.txt"
for e in "${array[@]}"
do
    echo "$e"
done

echo "DONE SCRIPT"

But whenever I run it, I get the following set of errors:

[jm@local Home]$ ./Parser.sh 
STARTING SCRIPT
./Parser.sh: line 9: [[[1542053213: command not found
./Parser.sh: line 9: [[-----------------------------------------: command not found
./Parser.sh: line 9: [[[1542053213: command not found
./Parser.sh: line 9: [[ERRHAND:: command not found
./Parser.sh: line 9: [[ERRHAND:: command not found
./Parser.sh: line 9: [[ERRHAND:: command not found
./Parser.sh: line 9: [[[1542053213: command not found
./Parser.sh: line 9: [[: command not found
./Parser.sh: line 9: [[[1542053213: command not found
DONE SCRIPT

Any advice would be greatly appreciated. I have tried looking at other posts but none have been able to really address my problem, which is creating a proper regex for the [2342323 s] pattern, and then adding that to an array. TiA

Upvotes: 2

Views: 1330

Answers (1)

Socowi
Socowi

Reputation: 27215

As pointed out in the comments

  • if [[ is missing its closing ]].
  • In a regex [ is not a literal, but starts a character group. To match something like [1234 s] you have to write \[[0-9]* s\].

To extract just the number 1234 from \[1234 s\] you can use tr, sed, perl -P, or a second grep -o.

Overall, your script seems way too complicated. You can drastically simplify it. Replace the for loop by mapfile and use grep -o to extract matches. You can replace your whole script with this

mapfile -t array < <(grep -o '\[[0-9]* s\]' logfile | tr -d '[] s')
printf '%s\n' "${array[@]}"

Note that if you only want to print the matches then you don't need an array. Just the grep part would be sufficient:

grep -o '\[[0-9]* s\]' logfile | tr -d '[] s'

Upvotes: 4

Related Questions