Inicializando múltiples variables en bash

2020-06-30 bash awk sed grep eval

Tengo un archivo con este contenido:

$ 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:[email protected]
Some other text

Ahora quiero grep PM1 a PM3 y quiero establecer algunas variables y usarlas en mi script:

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

Necesito una estructura que pueda usarse en más de PM1 a PM3. puede ser que yo también tenga PM10.

Está claro que podemos manipular cada campo, pero no sé cómo podemos usarlos.

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-

Actualizar

Necesito grep PM si la tercera letra es número. porque si no lo hago, puede confundirse con las contraseñas (último campo).

Answers

Una solución lenta, si no la más lenta, de bash shell para archivos de gran tamaño / datos.

#!/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[@]}"

La array se puede separar en una línea por entrada, ya que la solución actual agrupa la asignación y los valores por PM[0-9]* , si recorre la array , debería mostrar de lo que estoy hablando.

for i in "${[email protected]]}"; do
  echo "$i"
  echo
done

Aquí está la entrada separada para el valor de la matriz y las asignaciones, que pueden reemplazar la estructura de la array actual dependiendo de lo que esté haciendo.

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")

Una sola sed de comandos lo haría (usando sed de GNU, inputfile va a ser reemplazado con el nombre del archivo de entrada real):

sed -E -n 's/^PM([0-9]+):([^:]*):([^:]*):([^:]*):(.*)/user\1="\2"\nip\1="\3"\nport\1="\4"\npass\1="\5"/p' inputfile

salidas

user1="alex"
ip1="1.2.3.4"
port1="22"
pass1="passwordPM"
user2="alice"
ip2="5.6.7.8"
port2="1212"
pass2="Password"
user3="bob"
ip3="9.10.11.12"
port3="1313"
pass3="[email protected]"

Puede incrustar estas variables generadas en su secuencia de comandos de la siguiente manera:

#!/bin/bash

# Generate name=value pairs from inputfile and save them in a temporary file /tmp/variables
sed -E -n 's/^PM([0-9]+):([^:]*):([^:]*):([^:]*):(.*)/user\1="\2"\nip\1="\3"\nport\1="\4"\npass\1="\5"/p' inputfile > /tmp/variables || exit

# "Source" the file into script 
. /tmp/variables
# Temporary file is not needed any longer. You can remove it if you want

# You can use generated variable names from now on:
echo "user1=$user1"
# and the like

Related