Как объединить строки с отдельными столбцами до максимум 4 столбцов в одной строке?

Если вы хотите проверить, что вы изначально установили, проверьте раздел %packages файла /root/anaconda-ks.cfg

. минимальная установка, она должна выглядеть так:

@minimal
@core

Если вы устанавливали из Everything ISO и, например, указали установку графического сервера, она должна выглядеть так:

@graphical-server-environment
@base
@core
@desktop-debugging
@dial-up
@fonts
@gnome-desktop
@guest-agents
@guest-desktop-agents 
@input-methods
@internet-browser
@multimedia
@print-client
@x11
0
01.06.2017, 15:15
4 ответа

Немного идиоматично, но работает с gnu awk:

awk '{printf "%s",(NF==1?$0 FS:(c==0?"":RS) $0 RS)} \
{(NF==1?++c:c=0)} \
c==4{printf "\n";c=0} \
END{printf "\n"}' file

#Output
1 
4 5 6 7 19
20 22 
24 26 27
29 30 31 32 
34 40 50 56 
58 100 
234 235 270 500
1234 1235 1236 1237
2300 2303 2304 2307 
2309 

Объяснение:
переменные awk:
NF=количество полей
FS = Разделитель полей = пробел по умолчанию
RS=Разделитель записи= новая строка по умолчанию.
c=counter

Line1: {printf "%s",(NF==1?$0 FS:(c==0?"":RS) $0 RS)}: вложенные троичные операции if

#Single ternary if operation:
condition?true action:false action
#Nested if operations:  
condition1?true action 1:(condition2:true action2:false action2) #nested ternary if operations   
-------------------------[            ^ false action1 ^        ]   

Это можно объяснить псевдокодом, например:

if NF==1 then print $0 and print FS   
else (if c==0 then print "" else print RS) and print $0 and print RS again   

Строка 2: {(NF==1?++c:c=0)} : Еще одна троичная операция if, которая может быть выражена как:

If NF==1 (line has one field) 
then increase counter c by one 
else reset counter c.  

Строка 3: c==4{printf "\n";c=0} Классический синтаксис awk: условие{действие}

If counter c==4 then print a new line and reset counter c

Строка 4: END{printf "\n"}' file : это просто печатает новую строку в конце скрипта.

4
28.01.2020, 02:13

Вы можете использовать sed, чтобы получить то, что вы хотите:

sed -e '
   /./!b
   /[^[:space:]]/!b
   /[^[:space:]][[:blank:]]\{1,\}[^[:space:]]/b

   :loop
      $q;N
      /\n.*\S[[:blank:]]\+\S/b
      s/\n/ /;tdummy
      :dummy
      s/[[:space:]]\{1,\}/&/3;t
   bloop
' yourfile


Пояснения

  • Пропустить пустые, пустые и строки с NF > 1.
  • Настройка цикл do-while в точке, где пространство шаблона содержит строку с одним полем.
  • Мы берем следующую строку и проверяем, имеет ли она NF > 1, после чего печатаем все пространство шаблонов и возвращаемся к чтению следующей строки.
  • Теперь мы знаем, что следующая строка также состоит из одного поля, поэтому мы продолжим и обрежем новую строку, соединяющую эти две части в пространстве шаблона.
  • Есть ли в пространстве шаблонов фрагменты из 3 пробелов? Если да, то мы печатаем все пространство шаблона и начинаем читать следующую строку.
  • В противном случае мы возвращаемся к циклу, который, в свою очередь, считывает следующую строку, но прикрепляет ее к существующему пространству шаблонов.

Результат

1
4 5 6 7 19
20 22
24 26 27
29 30 31 32
34 40 50 56
58 100
234 235 270 500
1234 1235 1236 1237
2300 2303 2304 2307
2309
2
28.01.2020, 02:13

Использование: ./join_rows.awk input.txt

Проверьте shebang #!/usr/bin/awk -f, поскольку расположение awk может отличаться в вашей системе.

#!/usr/bin/awk -f

BEGIN {
    count = 1;
}

{
    if (NF == 1) {
        if (count > 1 && count <= 4) printf " ";

        printf "%s", $1;
        count++;

        if (count > 4) {
            printf "\n";
            count = 1;
        }
    } else {
        if (count > 1) printf "\n";

        print;
        count = 1;
    }
}

END {
    if(count > 1) printf "\n";
}

Вывод:

1
4 5 6 7 19
20 22 
24 26 27  
29 30 31 32
34 40 50 56
58 100
234 235 270 500
1234 1235 1236 1237 
2300 2303 2304 2307
2309
2
28.01.2020, 02:13

Расширенный gawk подход:

replace_columns.awk скрипт:

#!/bin/awk -f
function printRow(a, i, v)
{
    for (i in a) {
        printf "%s ", a[i]
    }
   print ""
   delete a
}
NF <= 2{
    for (i=1; i<=NF; i++) { 
        a[++c] = $i 
        if (length(a) == 4) {
            c = 0 
            printRow(a) 
        }
    }
}
NF > 2{
    if (length(a) > 0) {
        c = 0
        printRow(a)
    }
    print $0 
}
END{ print }

Использование :

awk -f rearrange_columns.awk yourfile

Вывод:

1 
4 5 6 7 19
20 22 
24 26 27 
29 30 31 32 
34 40 50 56 
58 100 
234 235 270 500
1234 1235 1236 1237
2300 2303 2304 2307 
2309
1
28.01.2020, 02:13

Теги

Похожие вопросы