Объединить строки между ключевыми словами в однострочные значения, разделенные запятыми

Оказывается, в Gentoo / Funtoo сопоставитель устройств для grub по умолчанию не включен. Я добавил следующее в /etc/portage/package.use :

sys-boot/grub device-mapper

Затем я повторно создал grub, запустил grub-install --target = x86_64-efi --efi-directory = / boot / efi --bootloader-id = "Funtoo Linux [GRUB]" --recheck и перезагрузился, чтобы найти экран запроса пароля luks. После ввода все загрузилось отлично.

Особая благодарность frostschutz, который предоставил решение в этой теме:

https://forums.gentoo.org/viewtopic.php?p=7972812#7972812

2
23.07.2016, 15:03
4 ответа

С GNU sed:

sed ':a;N;s/\n/,/;ta' file | sed 's/,Cat/\nCAT/g'

или

tr '\n' ',' < file | sed 's/,Cat/\nCAT/g'
2
27.01.2020, 21:54

awk

awk '
    /Cat/ {
        if (NR>1) print ""
        printf "%s", $0
        next
    } 
    {printf ",%s", $0} 
    END {print ""}
' file

Другая версия, которая сильно зависит от переменных awk: (добавлено до того, как я прочитал ваш комментарий о том, что "Cat" должен быть регистронезависимым регулярным выражением)

awk 'BEGIN {RS="Cat"; FS="\n"; OFS=","} NR>1 {$1=RS; NF--; print}' file
2
27.01.2020, 21:54

Это решение не требует чтения всего файла в память. Другими словами: он будет работать с файлом размером 1 ТБ, обрабатываемым на машине размером 1 ГБ, если полные строки меньше 1 ГБ.

perl -ne 'BEGIN { $sep = shift; }
          if(/^$sep$/o) { @p and print join(",", @p)."\n"; @p = (); }
          chomp; push @p, $_;
          END { print join(",", $sep, @p)."\n"; }' Cat /tmp/cat
1
27.01.2020, 21:54

Вы можете сделать что-то подобное с помощью sed:

sed '1{h;d;};/^Cat$/!{H;$!d;};x;s/\n/,/g;${x;/^Cat$/H;x;}' infile

explained:

sed '1{                   # if this is the 1st line
h                         # copy over the hold space
d                         # and delete it
}
/^Cat$/!{                 # if the line doesn't match Cat
H                         # append to hold space and
$!d                       # delete it if it's not the last line 
}
x                         # exchange pattern space w. hold buffer
s/\n/,/g                  # replace all newline chars with commas
${                        # check if the last line of input matches Cat:
x                         # exchange pattern space w. hold buffer
/^Cat$/H                  # if the line matches Cat append it to hold buffer
x                         # exchange back
}' infile
2
27.01.2020, 21:54

Теги

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