Как объединить каждые две строки в одну из командной строки? - PullRequest
125 голосов
/ 07 марта 2012

У меня есть текстовый файл в следующем формате.Первая строка - это «КЛЮЧ», а вторая - «ЗНАЧЕНИЕ».

KEY 4048:1736 string
3
KEY 0:1772 string
1
KEY 4192:1349 string
1
KEY 7329:2407 string
2
KEY 0:1774 string
1

Мне нужно значение в той же строке, что и ключ.Таким образом, результат должен выглядеть следующим образом ...

KEY 4048:1736 string 3
KEY 0:1772 string 1
KEY 4192:1349 string 1
KEY 7329:2407 string 2
KEY 0:1774 string 1

Было бы лучше, если бы я мог использовать такой разделитель, как $ или ,:

KEY 4048:1736 string , 3

Какобъединить две строки в одну?

Ответы [ 20 ]

209 голосов
/ 07 марта 2012

paste подходит для этой работы:

paste -d " "  - - < filename
151 голосов
/ 07 марта 2012

awk:

awk 'NR%2{printf "%s ",$0;next;}1' yourFile

обратите внимание, в конце вывода есть пустая строка.

sed:

sed 'N;s/\n/ /' yourFile
29 голосов
/ 27 октября 2015

Альтернатива sed, awk, grep:

xargs -n2 -d'\n'

Это лучше всего, когда вы хотите объединить N строк и вам нужен только вывод с разделителями.

Мой первоначальный ответ был xargs -n2, который отделяет слова, а не строки. -d может использоваться для разделения ввода на любой отдельный символ.

25 голосов
/ 07 марта 2012

Есть больше способов убить собаку, чем повесить. [1]

awk '{key=$0; getline; print key ", " $0;}'

Поместите любой желаемый разделитель в кавычки.


Ссылки:

  1. Первоначально "Множество способов убрать кошку с лица", возвращенное к более старому, потенциально возникающему выражению, которое также не имеет ничего общего с домашними животными.
11 голосов
/ 09 марта 2014

Вот еще один способ с awk:

awk 'ORS=NR%2?FS:RS' file

$ cat file
KEY 4048:1736 string
3
KEY 0:1772 string
1
KEY 4192:1349 string
1
KEY 7329:2407 string
2
KEY 0:1774 string
1

$ awk 'ORS=NR%2?FS:RS' file
KEY 4048:1736 string 3
KEY 0:1772 string 1
KEY 4192:1349 string 1
KEY 7329:2407 string 2
KEY 0:1774 string 1

Как указано Ed Morton в комментариях, этолучше добавить брекеты для безопасности и parens для переносимости.

awk '{ ORS = (NR%2 ? FS : RS) } 1' file

ORS означает разделитель выходной записи.Здесь мы тестируем условие, используя NR, в котором хранится номер строки.Если модуль NR является истинным значением (> 0), тогда мы устанавливаем Разделитель выходного поля на значение FS (Разделитель полей), которое по умолчанию является пробелом, в противном случае мы присваиваем значение RS (ЗаписьРазделитель), который является новой строкой.

Если вы хотите добавить , в качестве разделителя, используйте следующее:

awk '{ ORS = (NR%2 ? "," : RS) } 1' file
10 голосов
/ 08 марта 2012

Хотя кажется, что предыдущие решения будут работать, если в документе произойдет одна аномалия, выходные данные будут разбиты на части. Ниже немного безопаснее.

sed -n '/KEY/{
N
s/\n/ /p
}' somefile.txt
10 голосов
/ 07 марта 2012

Вот мое решение в bash:

while read line1; do read line2; echo "$line1, $line2"; done < data.txt
7 голосов
/ 28 марта 2014

"ex" - это редактор строк с возможностью написания сценариев, принадлежащий к тому же семейству, что и sed, awk, grep и т. Д. Я думаю, что это может быть то, что вы ищете.Многие современные клоны / наследники vi также имеют режим vi.

 ex -c "%g/KEY/j" -c "wq" data.txt

Это говорит о том, что для каждой строки, если она соответствует «KEY», выполните j oin следующей строки.После завершения этой команды (для всех строк) введите w rite и q uit.

4 голосов
/ 07 марта 2012

Если Perl является опцией, вы можете попробовать:

perl -0pe 's/(.*)\n(.*)\n/$1 $2\n/g' file.txt
4 голосов
/ 07 марта 2012

Вы можете использовать awk следующим образом, чтобы объединить 2 пары строк:

awk '{ if (NR%2 != 0) line=$0; else {printf("%s %s\n", line, $0); line="";} } \
     END {if (length(line)) print line;}' flle
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...