У меня есть такой файл:
abc 123
abc 789
bcd 456
acb 135
Я хотел бы напечатать первый столбец следующей строки в текущей строке.
Желаемый вывод:
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
Я предпочитаю использовать awk.
У меня есть такой файл:
abc 123
abc 789
bcd 456
acb 135
Я хотел бы напечатать первый столбец следующей строки в текущей строке.
Желаемый вывод:
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
Я предпочитаю использовать awk.
Ответы:
Запомните предыдущую строку:
awk 'NR > 1 { print prev, $1 } { prev = $0 } END { print prev }'
Это обрабатывает ввод следующим образом:
prev, см. следующий шаг) и первое поле текущей строки, разделенные разделителем выходного поля (по умолчанию символ пробела);prevпеременной;Альтернативный 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
Та же самая идея о заключительном переводе строки применяется здесь.
Вот уродливый 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 ' ' - - склеить этот беспорядок (добавить вторую строку к третьей, четвертую строку к третьей и т. д.)sedпрограммы для развлечения, то, возможно, вам стоит попробовать себя в code-golf ;-)
На мой взгляд, самый простой и читаемый подход:
cut)tail)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
Структура этого решения отличается от приведенных ответов. Нет необходимости условий, циклов или регулярных выражений.
sedсамостоятельно безpaste:sed -r 'N;s/\n(\w+)/\1&/;P;D' somefile.txt