Search code examples
bashawksedgrepeval

Initializing multiple variables in bash


I have a file with this content:

$ cat init
Sample text
PM1:alex:1.2.3.4:22:passwordPM
PM2:alice:5.6.7.8:1212:Password
PM3:bob:9.10.11.12:1313:p@ssword
Some other text

Now I want to grep PM1 to PM3 and I want to set some variables and use them in my script:

user1="alex"
ip1="1.2.3.4"
port1="22"
pass1="password"
...

I need an structure could be used in more than PM1 to PM3. may be I have also PM10.

It's clear that we can grep each field but I don't know how we can use them.

grep PM init | cut -d: -f2
grep PM init | cut -d: -f3
grep PM init | cut -d: -f4
# I need to grep field number 5 in this way:
grep PM init | cut -d: -f5-

Update

I need to grep PM if the third letter is number. because if I don't do it may mixed up with passwords(last field).


Solution

  • A slow if not the slowest bash shell solution for large data/size files.

    #!/usr/bin/env bash
    
    while read -r lines; do
      if [[ $lines == PM[0-9]* ]]; then
        IFS=: read -r pm user ip port pass <<< "$lines"
        n=${pm#*??}
        printf -v output 'user%s="%s"\nip%s="%s"\nport%s="%s"\npass%s="%s"' "$n" "$user" "$n" "$ip" "$n" "$port" "$n" "$pass"
        array+=("$output")
      fi
    done < init
    
    printf '%s\n' "${array[@]}"
    

    The array can be separated in one line per entry, since the current solution groups the assignment and values per PM[0-9]*, if you loop over the array it should show what I'm talking about.

    for i in "${array@]}"; do
      echo "$i"
      echo
    done
    

    Here is the separate entry for the array value and assignments, which can replace the current array structure depending on what you're doing.

    printf -v user 'user%s="%s"' "$n" "$user"
    printf -v ip 'ip%s="%s"' "$n" "$ip"
    printf -v port 'port%s="%s"' "$n" "$port"
    printf -v pass 'pass%s="%s"' "$n" "$pass"
    array+=("$user" "$ip" "$port" "$pass")