2

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

6
  • if [[$line =~ [\d\ws]; then should be: if [[ $line =~ [a-zA-Z0-9_s] ]]; then Commented Nov 13, 2018 at 21:54
  • Hi @anubhava, thank you for the answer. I think you noticed I did miss my closing brackets, but that regular expression returns every line, not just the values enclosed within the brackets. Commented Nov 13, 2018 at 21:57
  • Yes I knew that regex is wrong but it is equivalent of what you used [\d\ws]. I need more details from you about regex to suggest you the correct one. Commented Nov 13, 2018 at 22:00
  • Is sed -En '/\[[0-9]+ s\]/ { s/^.*\[([0-9]+ s)\].*/\1/; p; }' log useful, or do you need it to be a bash script? Commented Nov 13, 2018 at 22:00
  • Please read the description of tags before applying them. The "linux" tag was wrong here. Commented Nov 13, 2018 at 22:05

1 Answer 1

4

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'
Sign up to request clarification or add additional context in comments.

3 Comments

Hi @Socowi I appreciate your response. This solves my problem. Thank you.
If I wanted to just get the numbers, and not the space and 's', might you have advice on how to edit the given regex to match that condition (this is more for my personal learning)
@JerryM. Glad I could help. I edited the answer such that only the numbers are extracted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.