Помощь с форматированием текста

Помощь с форматированием текста

Мне нужна помощь с bash-скриптингом. Ниже приведен мой вклад:

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

Результат должен выглядеть так:

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

Я попробовал sed -n '/cn:/,/cn:/p' file, но это не дало того, что мне нужно.

решение1

с помощью awkкоторого можно выбрать подходящий инструмент для форматирования текста:

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

решение2

С использованием 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

В качестве «однострочника»:

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

Аналогичный подход к вышеизложенному awk:

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

Оба варианта sedи awkв этом ответе (а также shвариант в конце ниже) справятся с пробелами в данных, как в строках, MGтак и в userстроках:

$ 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

В качестве забавного упражнения используйте /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

Бежать с

sh script.sh <file

решение3

Учитывая ваш пример ввода выше, вы можете использовать это:

#!/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

Например:

$ 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
$

Скрипт запускает цикл, который считывает строку текста. Если строка начинается с Grp:, то он сохраняет второй токен, разделенный пробелом, как group. Если строка пустая, то он печатает пустую строку. В противном случае он печатает последнюю прочитанную группу, за которой следует запятая, а затем содержимое строки.

Связанный контент