У меня есть текстовый файл в следующем формате. Первая строка - это «КЛЮЧ», а вторая - «ЗНАЧЕНИЕ».
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
Как мне объединить две строки в одну?
pr
,paste
,awk
,xargs
,sed
иpure bash
! (xargs
медленнее, медленнее, чем Баш !)Ответы:
AWK:
обратите внимание, в конце вывода есть пустая строка.
СЭД:
источник
printf
строки расширения, подобные . Этого сбоя можно избежать следующим образом:%s
$0
'NR%2{printf "%s ",$0;next;}1'
1
после закрывающей скобки?paste
хорош для этой работы:источник
paste
с другой стороны, ведет себя отлично. +1.cut
но всегда забываюpaste
. Это качается для этой проблемы. Мне нужно было объединить все строки из стандартного ввода и сделать это легкоpaste -sd ' ' -
.-
значит stdin, такpaste - -
что читайте из stdin, а затем читайте из stdin, вы можете сложить столько их, сколько хотите, как я ожидаю.Альтернатива sed, awk, grep:
Это лучше всего, когда вы хотите объединить N строк и вам нужен только вывод с разделителями.
Мой оригинальный ответ был
xargs -n2
разделен на слова, а не на строки.-d
может использоваться для разделения ввода на любой отдельный символ.источник
-d '\n'
xargs
пользователь, но не знал этого. Отличный совет.Есть больше способов убить собаку, чем повесить. [1]
Поместите любой разделитель в кавычки.
Ссылки:
источник
$0
. Командаgetline
также захватывает «следующую» строку ввода и помещает ее в$0
. Таким образом, первый оператор захватывает первую строку, а команда print объединяет то, что было сохранено в переменной,key
со строкой, содержащей запятую, вместе со строкой, полученной с помощьюgetline
. Яснее? :)Вот мое решение в Bash:
источник
Хотя кажется, что предыдущие решения будут работать, если в документе произойдет одна аномалия, выходные данные будут разбиты на части. Ниже немного безопаснее.
источник
/KEY/
? Чтоp
делать в конце?/KEY/
поиски прямой сKEY
. чтоp
выводит результат из. это безопаснее, потому что он применяет операцию только к строкам,KEY
в которых есть.Вот еще один способ с
awk
:Как указал Эд Мортон в комментариях, лучше добавить скобки для безопасности и парены для переносимости.
ORS
расшифровывается как разделитель выходных записей. Здесь мы тестируем условие, используяNR
которое хранит номер строки. Если модульNR
является истинным значением (> 0), тогда мы устанавливаем Разделитель выходного поля на значениеFS
(Разделитель полей), которое по умолчанию является пробелом, в противном случае мы присваиваем значениеRS
(Разделитель записей), которое является символом новой строки.Если вы хотите добавить
,
в качестве разделителя, используйте следующее:источник
ORS
и с этим обращаются, такtrue
как ORS получает значение, которое не равно нулю или пустой строке, и удивляется, правильно догадываясь, что это должно быть жало вместо числового сравнения? Это что-то еще? Я действительно не уверен, и поэтому я написал бы это какawk '{ORS=(NR%2?FS:RS)}1' file
. Я заключил в скобки троичное выражение, чтобы обеспечить переносимость.«ex» - это редактор строк с возможностью написания сценариев, принадлежащий к тому же семейству, что и sed, awk, grep и т. д. Я думаю, что это может быть то, что вы ищете. Многие современные клоны / наследники vi также имеют режим vi.
Это говорит для каждой строки, если она соответствует «KEY» выполнить J ойн следующей строки. После этого завершения команды (против всех линий), выдавать ш обрядового и д ПИФ.
источник
Если Perl является опцией, вы можете попробовать:
источник
-0
perl установить разделитель записей ($/)
на ноль, чтобы мы могли охватить несколько строк в нашем шаблоне сопоставления. Руководства слишком технические, чтобы я мог понять, что это означает на практике.Вы можете использовать awk следующим образом, чтобы объединить две пары строк:
источник
Другие решения, использующие vim (только для справки).
Решение 1 :
Откройте файл в vim
vim filename
, затем выполните команду:% normal Jj
Эту команду очень легко понять:
После этого сохраните файл и выйдите с
:wq
Решение 2 :
Выполните команду в оболочке,
vim -c ":% normal Jj" filename
затем сохраните файл и выйдите с помощью:wq
.источник
norm!
надежнее, чтоnormal
в случаеJ
был переназначен. +1 за vim решение.Вы также можете использовать следующую команду vi:
источник
:%g//j
поскольку все, что вам нужно, - это совпадение для выполняемого объединения , а нулевая строка все еще является допустимым регулярным выражением.//
, вместо этого будет использоваться предыдущий шаблон поиска. Если предыдущего шаблона нет, Vim просто сообщает об ошибке и ничего не делает. Решение Дждамяна работает постоянно.Небольшое изменение в ответе Гленна Джекмана с использованием
paste
: если значение для параметра-d
разделителя содержит более одного символа,paste
циклически перебирает символы по одному и в сочетании с-s
параметрами продолжает делать это при обработке одного и того же входного файла.Это означает, что мы можем использовать все, что хотим, в качестве разделителя плюс escape-последовательность
\n
для объединения двух строк одновременно.Используя запятую:
и знак доллара:
Чего нельзя сделать, так это использовать разделитель, состоящий из нескольких символов.
В качестве бонуса, если
paste
он совместим с POSIX, это не приведет к изменению новой строки последней строки в файле, поэтому для входного файла с нечетным числом строк, напримерpaste
не будет привязываться к символу разделения в последней строке:источник
Это читается как
источник
В случае, когда мне нужно было объединить две строки (для облегчения обработки), но разрешить данные за конкретным, я нашел это полезным
data.txt
вывод тогда выглядит так:
converted_data.txt
источник
Другой подход с использованием vim:
Это относится
join
(к строке ниже) ко всем строкам, в которых есть словоKEY
. Результат:источник
Самый простой способ здесь:
источник
-0
поглощает весь файл вместо того, чтобы читать его построчно;pE
оборачивает код в цикл и печатает вывод, подробности см. в http://perldoc.perl.org/perlrun.html ;^KEY
совпадение «KEY» в начале строки, за которым следует не жадное сопоставление что-либо (.*?
) перед последовательностью\s+
любого вида, включая разрывы строк;(\d+)
которые мы записываем и позже вставляем как$1
;с последующим концом строки
$
.\K
Удобно исключает все слева от замены, поэтому{ $1}
заменяет только 1-2 последовательности, см. http://perldoc.perl.org/perlre.html .источник
Более общее решение (допускает объединение нескольких последующих строк) в виде сценария оболочки. Это добавляет грань между каждым, потому что мне нужна была видимость, но это легко исправить. В этом примере строка «ключа» оканчивалась на: другие строки не делали.
источник
Попробуйте следующую строку:
Поместить разделитель между
например, если разделитель
|
, то:источник
Вы можете использовать
xargs
как это:источник
xargs -n 2
но этот ответ не объясняет это вообще.