Как использовать awk / sed для переформатирования этого текста - PullRequest
0 голосов
/ 21 июня 2019

все.У меня есть такой текстовый файл:

1
question1
answer1
2
question2
answer2
3
question3
answer3
<etc>

Я прочитал (и безуспешно пытался) много разных способов, используя awk.Я не программист, поэтому awk трудно понять.

Многие из вас являются экспертами в awk, поэтому я надеюсь, что вы покажете мне правильную команду:сделайте это.

Спасибо за вашу помощь!

Я хотел бы убрать пронумерованные строки (1-й, 4-й, 7-й и т. д.), а затем поставить запятую между вопросами и ответами, чтобыПолученный текстовый файл выглядит так:

question1, answer1
question2, answer2
question3, answer3
<etc>

Ответы [ 4 ]

3 голосов
/ 21 июня 2019
$ awk '{n=NR%3} n!=1{printf "%s%s", $0, (n?", ":ORS)}' file
question1, answer1
question2, answer2
question3, answer3
2 голосов
/ 21 июня 2019

С GNU sed. Удалите каждую третью строку, начиная с первой строки (1~3d), добавьте следующую строку ввода в шаблонное пространство sed (N) и замените теперь содержащуюся новую строку в шаблонном пространстве sed (s/\n/, /).

sed '1~3d; N; s/\n/, /' file

Выход:

question1, answer1
question2, answer2
question3, answer3
1 голос
/ 21 июня 2019

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

sed -n 'n;N;s/\n/, /p' file

Sed по умолчанию будет печатать каждую строку, которую он обрабатывает, однако вы можете отключить это с помощью опции -n, и теперь sed будетпечатать только тогда, когда мы этого хотим.

Команда n обычно печатает текущую строку и заменяет ее следующей, но, поскольку мы попросили ее печатать только по требованию, она эффективно теряет текущую строку.

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

Команда s/\n/, /p заменяет эту новую строку на ,, за которым следуетпространство.Флаг p в конце команды замещения печатает все, что находится в текущей строке, если замещение было успешным.Поскольку мы построили текущую строку так, чтобы в ней была новая строка (N), мы знаем, что это всегда будет происходить.

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

Несколько альтернатив:

sed 'N;s/.*\n//;N;s/\n/, /' file

sed 'N;N;s/.*\n\(.*\)\n/\1, /' file

sed -En 'n;N;G;s/(.)(.*)\1$/, \2/' file

Последнее решение похоже на первое, но никогда не ссылается непосредственно на новую строку.

0 голосов
/ 21 июня 2019

Это похоже на работу:

awk '{
    if ($0 ~ /^[0-9]+$/) {
       /* eliminates lines of all numbers */
    } else if (x == "") {
        /* save until next line is available */
        x = $1;
    } else {
        /* print both */
        print x "," $1;
        /* reset flag */
        x = "";
    }
}'

Это не самый элегантный awk, так как он более процедурный, чем шаблон -> действие, для которого он предназначен ....

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...