Использование awk (или sed) для удаления новых строк на основе первого символа следующей строки - PullRequest
8 голосов
/ 05 февраля 2010

вот моя ситуация: у меня был большой текстовый файл, из которого я хотел получить определенную информацию. Я использовал sed для извлечения всей соответствующей информации, основанной на регулярных выражениях, но каждая «часть» информации, которую я извлек, находится на отдельной строке, я бы хотел, чтобы каждая «запись» была на отдельной строке, чтобы ее можно было легко импортировать в БД.
Вот образец моих данных прямо сейчас:

92831,499,000
, 0644321
79217,999,000
, 5417178
, PK91622
, PK90755

В идеале я бы хотел, чтобы этот вывод выглядел следующим образом:

92831,499,000 , 0644321
79217.999.000 , 5417178 , PK91622
79217.999.000 , 5417178 , PK90755

Это может быть труднее сделать, поэтому я предпочел бы, чтобы вывод этой последней "записи" появлялся только один раз, а дополнительное "PK ..." было четвертым "полем" этой строки.
В конце концов, самый простой способ сделать это, если строка начинается с запятой (^,) новой строки перед ее удалением ... Хотя я не слишком знаком с awk, так что если вы могли бы дать мне Начнем с этого, это действительно будет оценено! Спасибо!

Ответы [ 5 ]

6 голосов
/ 05 февраля 2010
$ perl -0pe 's/\n,/,/g' < test.dat
92831,499,000,0644321
79217,999,000,5417178,PK91622,PK90755

Перевод: массовое чтение без разделения строк, заменяйте каждую запятую после новой строки только запятой.

Самый короткий код здесь!

2 голосов
/ 05 февраля 2010

Ну, думаю, мне следовало бы поближе взглянуть на использование Records в awk, когда я пытался выяснить это вчера вечером ... Через 10 минут после их просмотра у меня получилось. Для всех интересующихся вот как я это сделал: В моем оригинальном сценарии sed я вставил дополнительный символ новой строки перед началом каждой записи, так что теперь есть пустая строка, разделяющая каждую. Затем я использую следующую команду awk:

awk 'BEGIN {RS = ""; FS = "\ n"}
{
if (NF> = 3)
для (i = 3; i <= NF; i ++) <br> печать 1, 2, я
} '

и он работает как заклинание, выводя именно то, что я хотел!

1 голос
/ 03 декабря 2011

Это может работать для вас:

# sed ':a;N;s/\n,/,/;ta;P;D' test.dat | sed 's/,/\n/5;s/\(.*,\).*\n/&\1/'
92831,499,000,0644321
79217,999,000,5417178,PK91622
79217,999,000,5417178,PK90755

Пояснение:

Это состоит из двух частей:

Добавьте следующую строку, а затем, если добавленная строка начинается с ,, удалите встроенную новую строку \n и начните снова. Если не печатать до новой строки, а затем удалить до новой строки. Повторите.

Заменить 5-е , новой строкой. Затем вставьте первые четыре поля между встроенной новой строкой и шестым полем.

1 голос
/ 05 февраля 2010

Без специального кожуха 3, легко.

awk '
    !/^,/   { if (NR > 1) print x ; x = $0 }
    /^,/    { x = x OFS $0 }
    END     { if (NR) print x }
'

С, более сложный, но все же не слишком сложный.

awk '
    !/^,/   { if (n && n < 3) print x ; x = $0 ; n = 1 }
    /^,/    { if (++n > 2) { print x, $0 } else { x = x OFS $0 } }
    END     { if (n && n < 3) print x }
'
1 голос
/ 05 февраля 2010
sedsed -d -n ':t;/^,/!x;H;n;/^,/{x;$!bt;x;H};x;s/\n//g;p;${x;/^,/!p}' filename
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...