Ayuda con el formato de texto

Ayuda con el formato de texto

Necesito ayuda con las secuencias de comandos bash. A continuación se muestra mi opinión:

Grp: MG1
user1 
user2 
user3 
Grp: MG2
user7 
user1 
user9 
user6 
user2 

El resultado debería verse así:

Reporting MG1
MG1,user1 
MG1,user2 
MG1,user3 
Reporting MG2
MG2,user7 
MG2,user1 
MG2,user9 
MG2,user6 
MG2,user2 

Lo intenté sed -n '/cn:/,/cn:/p' file, pero no hizo lo que quería.

Respuesta1

con awkcuál es la herramienta adecuada para formatear texto:

awk '/^Grp:/ { OFS=" "; $1= "Reporting"; mg=$2; print; next} 
             { OFS=","; print mg, $0}' infile

Respuesta2

Usando sed:

$ cat script.sed
/^Grp: / {                              ;# A "Grp: " line
        s///                            ;# Remove "Grp: "
        h                               ;# Save in hold space
        s/^/Reporting /p                ;# Insert "Reporting " at start, print
        d                               ;# Delete, start next cycle
}

# Any other line:
G                               ;# Append the hold space
s/\(.*\)\n\(.*\)/\2,\1/         ;# Swap strings around \n, insert comma
$ sed -f script.sed file
Reporting MG1
MG1,user1
MG1,user2
MG1,user3
Reporting MG2
MG2,user7
MG2,user1
MG2,user9
MG2,user6
MG2,user2

Como "una sola línea":

sed -e '/^Grp: /{s///;h;s/^/Reporting /p;d;}' \
    -e 'G;s/\(.*\)\n\(.*\)/\2,\1/' file

Un enfoque similar al anterior con awk:

awk '/^Grp: / { sub("^Grp: ", ""); group = $0; print "Reporting " $0; next }
              { print group "," $0 }' file

Tanto las variaciones sedcomo awken esta respuesta (así como la shvariante al final a continuación) se encargarían de los espacios en los datos, ya sea en las MGcadenas o en las usercadenas:

$ cat file
Grp: some group ID
line 1
the other line
$ sed -e '/^Grp: /{s///;h;s/^/Reporting /p;d;}' -e 'G;s/\(.*\)\n\(.*\)/\2,\1/' file
Reporting some group ID
some group ID,line 1
some group ID,the other line

Como ejercicio divertido, utilice /bin/sh:

while IFS= read -r line; do
        case $line in
                'Grp: '*)
                        group=${line#Grp: }
                        printf 'Reporting %s\n' "$group"
                        ;;
                *)
                        printf '%s,%s\n' "$group" "$line"
        esac
done

Corre con

sh script.sh <file

Respuesta3

Dada la entrada de ejemplo anterior, puede usar esto:

#!/bin/bash

group=""

while read line; do
    if [[ "${line}" =~ ^Grp:* ]]; then
        group="$(echo "${line}" | awk '{ print $2 }')"
        echo "Reporting ${group}"
    elif [[ "${line}" == "" ]]; then
        echo
    else
        echo "${group},${line}"
    fi
done

Por ejemplo:

$ cat input
Grp: MG1
user1
user2
user3
Grp: MG2
user7
user1
user9
user6
user2
$

$ ./ex.sh < input
Reporting MG1
MG1,user1
MG1,user2
MG1,user3
Reporting MG2
MG2,user7
MG2,user1
MG2,user9
MG2,user6
MG2,user2
$

El script ejecuta un bucle que lee una línea de texto. Si la línea comienza con Grp:, guarda el segundo token delimitado por espacios en blanco como group. Si la línea está en blanco, imprime una línea en blanco. De lo contrario, imprime el grupo de la última lectura, seguido de una coma y seguido del contenido de la línea.

información relacionada