Согласите несколько строк в одну строку, пока не найден шаблон

Есть паллиатив.

Я добавил сочетание клавиш в терминал ( ~ / .bashrc ), которое рисует какой-то цветной маркер (на самом деле, зеленую линию в моем случае).

print_green_line() {
  echo "$(tput setaf 2)________________________________________$(tput sgr 0)"
}
bind -x '"\eG": print_green_line' # Alt+Shift+G

После маркера я начинаю свою длинную команду вывода. Теперь, когда я прокручиваю вверх, легко найти начало вывода команды.

1
18.08.2018, 00:23
5 ответов
sed ':L; ${s/\n/,/g; s/,|,/\n/g; s/|,\|,|//g};  N; bL;' file
1
27.01.2020, 23:12

Один из способов сделать это:

perl -nF'\|\n' -a0777e 'print s/\n(?!\z)/,/gr for @F' input.file

Пояснение:

  • Выделите файл -0777, а затем разделите его на -F\|\n, т. е. везде, где мы видим символ вертикальной черты, за которым следует символ новой строки.
  • Опция -aсохранит разделяемые поля в массиве @F, который имеет нулевой -индекс.
  • Первый элемент массива @F, а именно $F[0], будет пустым, поэтому не будет отображаться при печати.
  • Цикл forперебирает все элементы массива @Fи для каждого элемента изменяет все те новые строки, которые не видят конец -строки -непосредственно справа, (?!\z), заменяются запятой.

Выход:

9000,3000,1000,0000,0000,2000,1000,2000
5669000,518000,3000,16000,0000,28000,2241000,2841000
9020000,453000,520000,4000,2852000,5191000,75000

Еще один метод с использованиемPOSIXредактора ly sed. Здесь мы загружаем пространство шаблона настолько, насколько это необходимо для принятия решения о его печати :

.
sed -e '
    /|$/!ba
    1d;s/\n|$//
    :b;y/\n/,/;b
    :a;$bb
    N;H;s/.*//;x;D
' input.file

В этом методе мы глотаем файл:

sed -e '
    $!{                 ;# provided we"re not at the eof
        N;H;s/.*//;x;D  ;# we stick the next line to the PS & keep doing it till we hit the eof.
    }

    ;# here we have the whole file loaded into the pattern space, PS
    s/^|\n//;s/\n|$//   ;# take away the leading and trailing pipes
    s/\n|\n/,/g         ;# the internal pipes are changed to commas
    y/\n,/,\n/          ;# interchange the newlines <=> commas
' input.file

С помощью GNU sedэто можно сделать, настроив цикл do -until для загрузки пространства шаблонов, пока мы еще не видели символ |. Обратите внимание :при этом мы предполагаем, что последняя и первая строки ввода обязательно имеют символ |.

sed -e '
    1d
    :loop
        $!N
        s/\n|//
    Tloop
    y/\n/,/
' input.file
1
27.01.2020, 23:12
awk -vRS='|' -vOFS=, '$1=$1""' infile
  • Оператор RS='|'заменяет awk-оператор по умолчанию R запись S , который он \newline на канал |.
  • Оператор OFS=,изменяет оператор awk по умолчанию O вывода F поле S вместо пробела на запятую ,.

  • $1==$1(вы можете использовать любое поле )вызывает повторную -оценку$0(известной целой строки в awk )и объединяет поля на основе RS как |и OFS как ,.

  • Двойные кавычки в '$1=$1""'используются для принудительного присвоения awk строк, поэтому строка только с нулевым (s )не будет удалена.

  • Выход:

    9000,3000,1000,0000,0000,2000,1000,2000
    5669000,518000,3000,16000,0000,28000,2241000,2841000
    9020000,453000,520000,4000,2852000,5191000,75000
    
1
27.01.2020, 23:12

Кажется, это хорошо работает:

$ tr "|\n" "\n," < input | sed 's/^,//;s/,$//'
9000,3000,1000,0000,0000,2000,1000,2000
5669000,518000,3000,16000,0000,28000,2241000,2841000
9020000,453000,520000,4000,2852000,5191000,75000

Мы используем trдля перевода |s в новые строки, а символы новой строки — в ,s. Затем мы берем результирующий вывод и удаляем начальные или конечные ,с sed.

2
27.01.2020, 23:12

awkрешение. Подозреваю, что это немного длинно -затянуто.

$ awk 'BEGIN{RS="|"}NF>1{print substr(gensub(/\n/,",","g"),2,length($0)-2)}' file
9000,3000,1000,0000,0000,2000,1000,2000
5669000,518000,3000,16000,0000,28000,2241000,2841000
9020000,453000,520000,4000,2852000,5191000,75000
$

Попробуйте онлайн!

3
27.01.2020, 23:12

Теги

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