Как напечатать первый столбец следующей строки в текущей строке?

8

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

abc 123    
abc 789  
bcd 456  
acb 135

Я хотел бы напечатать первый столбец следующей строки в текущей строке.

Желаемый вывод:

abc  123 abc  
abc 789 bcd  
bcd 456 acb  
acb 135 

Я предпочитаю использовать awk.

user2905046
источник

Ответы:

16

Запомните предыдущую строку:

awk 'NR > 1 { print prev, $1 } { prev = $0 } END { print prev }'

Это обрабатывает ввод следующим образом:

  • если текущая строка является второй или большей, выведите предыдущую строку (сохраненную в prev, см. следующий шаг) и первое поле текущей строки, разделенные разделителем выходного поля (по умолчанию символ пробела);
  • во всех случаях сохраняйте текущую строку в prevпеременной;
  • в конце файла выведите предыдущую строку.
Стивен Китт
источник
11

Альтернативный awkподход:

$ awk 'NR == 1{printf "%s", $0;next}{printf " %s\n%s", $1,$0}' input.txt                                    
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135

Это работает просто: первая строка - это особый случай - мы печатаем ее без новой строки и сообщаем awk перейти на следующую строку без выполнения других блоков кода. После этого NR == 1{printf "%s", $0;next}пропускается, но другие части делают работу.

Помните, что до сих пор мы печатали отформатированную строку без символа новой строки. Таким образом, printf " %s\n%s",$1,$0сейчас выполняется вывод первого слова (и поскольку новой строки не было, она остается на той же строке вывода), вставляется новая строка, а затем вся строка (но не заканчивается символом новой строки) , Таким образом, следующее первое введенное слово останется в той же строке. Процесс продолжается и продолжается, пока мы не достигнем конца файла.

Возможное улучшение состоит в том, чтобы включить END{print ""}блок для вставки последней строки. В некоторых случаях, когда полученный файл должен обрабатываться другими сценариями, это может быть желательно.


Хотя пользователь специально запрашивал AWK, такой же подход к печати форматированных строк можно использовать и с другими языками, например Python. Альтернатива Python предназначена для тех, кому интересно, как это можно реализовать на других языках:

#!/usr/bin/env python
from __future__ import print_function
import sys

old = None
for index,line in enumerate(sys.stdin):
    if index == 0:
        print(line.strip(),end=" ")
        continue
    words = line.strip().split()
    print(words[0] + "\n" + line.strip(),end=" ")

И использование вроде так:

$ ./append_first.py < input.txt                            
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135

Та же самая идея о заключительном переводе строки применяется здесь.

Сергей Колодяжный
источник
9

Вот уродливый sedспособ просто для удовольствия

sed '2,$ s/[^ ]\+/& &/; 2,$ s/ /\n/' file | paste -d ' ' - -
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135 

объяснение

  • 2,$ от второй строки до последней
  • s/[^ ]\+/& &/ удвоить первый набор непробельных символов
  • ; разделяет команды, как в оболочке
  • s/ /\n/ заменить первый пробел новой строкой
  • paste -d ' ' - - склеить этот беспорядок (добавить вторую строку к третьей, четвертую строку к третьей и т. д.)
Занна
источник
1
В качестве альтернативы вы можете использовать sedсамостоятельно без paste:sed -r 'N;s/\n(\w+)/\1&/;P;D' somefile.txt
Цифровой травмы
1
Если вы пишете sedпрограммы для развлечения, то, возможно, вам стоит попробовать себя в code-golf ;-)
Digital Trauma
1
@DigitalTrauma она уже два месяца занимается код-гольфом;)
Сергей Колодяжный
1

На мой взгляд, самый простой и читаемый подход:

  1. извлечь первый столбец ( cut)
  2. удалить первую строку из вашего извлеченного столбца ( tail)
  3. вставьте этот столбец в ваш исходный файл ( paste)

Пример: ваш пример выходного файла:

abc 123    
abc 789  
bcd 456  
acb 135

Затем выполните следующую команду в терминале

cut -d' ' -f1 in.txt | tail -n +2 | paste -d' ' file -

Вывод:

abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135

Структура этого решения отличается от приведенных ответов. Нет необходимости условий, циклов или регулярных выражений.

Гельдерлин
источник