Печать всего, кроме первого поля, с помощью awk - PullRequest
93 голосов
/ 16 ноября 2010

У меня есть файл, который выглядит следующим образом:

AE  United Arab Emirates
AG  Antigua & Barbuda
AN  Netherlands Antilles
AS  American Samoa
BA  Bosnia and Herzegovina
BF  Burkina Faso
BN  Brunei Darussalam

И я хотел бы инвертировать заказ, печатая сначала все, кроме 1 доллара, а затем 1:

United Arab Emirates AE

Какможно сделать трюк "все, кроме поля 1"?

Ответы [ 15 ]

97 голосов
/ 27 октября 2011

$1="" оставляет пробел, как упоминал Бен Джексон, поэтому используйте цикл for:

awk '{for (i=2; i<=NF; i++) print $i}' filename

Так что, если ваша строка была "один два три", вывод будет:

дваthree

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

awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}' filename

Это даст вам: "two three"

75 голосов
/ 16 ноября 2010

Назначение $1 работает, но оно оставляет начальный пробел: awk '{first = $1; $1 = ""; print $0, first; }'

Вы также можете найти количество столбцов в NF и использовать его в цикле.

61 голосов
/ 06 июня 2013

Используйте команду cut с параметром --complement:

$ echo a b c | cut -f 1 -d ' '
a
$ echo a b c | cut -f 1,2 -d ' '
a b
$ echo a b c | cut -f 1 -d ' ' --complement
b c
20 голосов
/ 07 апреля 2014

Может быть, самый краткий способ:

$ awk '{$(NF+1)=$1;$1=""}sub(FS,"")' infile
United Arab Emirates AE
Antigua & Barbuda AG
Netherlands Antilles AN
American Samoa AS
Bosnia and Herzegovina BA
Burkina Faso BF
Brunei Darussalam BN

Пояснение:

$(NF+1)=$1: Генератор «нового» последнего поля.

$1="": установить исходное первое поле равным нулю

sub(FS,""): после первых двух действий {$(NF+1)=$1;$1=""} избавиться от первого разделителя полей с помощью sub. Окончательный вариант неявного.

13 голосов
/ 06 августа 2015
awk '{sub($1 FS,"")}7' YourFile

Удалите первое поле и разделитель и напечатайте результат (7 - ненулевое значение, поэтому выведите $ 0).

9 голосов
/ 19 апреля 2012
awk '{ saved = $1; $1 = ""; print substr($0, 2), saved }'

При установке первого поля на "" остается одна копия OFS в начале $0.Предполагая, что OFS является только одним символом (по умолчанию это один пробел), мы можем удалить его с помощью substr($0, 2).Затем добавляем сохраненную копию $1.

5 голосов
/ 10 сентября 2015

Если вы открыты для решения Perl ...

perl -lane 'print join " ",@F[1..$#F,0]' file

- это простое решение с разделителем ввода / вывода из одного пробела, которое дает:

United Arab Emirates AE
Antigua & Barbuda AG
Netherlands Antilles AN
American Samoa AS
Bosnia and Herzegovina BA
Burkina Faso BF
Brunei Darussalam BN

Этот следующий немного сложнее

perl -F`  ` -lane 'print join "  ",@F[1..$#F,0]' file

и предполагает, что разделитель ввода / вывода состоит из двух пробелов:

United Arab Emirates  AE
Antigua & Barbuda  AG
Netherlands Antilles  AN
American Samoa  AS
Bosnia and Herzegovina  BA
Burkina Faso  BF
Brunei Darussalam  BN

Используются следующие параметры командной строки:

  • -n цикл вокруг каждой строки входного файла, не печатать автоматически каждую строку

  • -l удаляет символы новой строки перед обработкой и добавляет их обратно

  • -a режим автоматического разделения - разбить входные строки на массив @F. По умолчанию расщепление по пробелам

  • -F модификатор autosplit, в этом примере разделяется на '' (два пробела)

  • -e выполнить следующий код perl

@F - массив слов в каждой строке, проиндексированный, начиная с 0
$#F - количество слов в @F
@F[1..$#F] - это фрагмент массива элемента от 1 до последнего элемента
@F[1..$#F,0] - это фрагмент массива от элемента 1 до последнего элемента плюс элемент 0

2 голосов
/ 14 ноября 2013

Давайте переместим все записи к следующей и установим последнюю как первую:

$ awk '{a=$1; for (i=2; i<=NF; i++) $(i-1)=$i; $NF=a}1' file
United Arab Emirates AE
Antigua & Barbuda AG
Netherlands Antilles AN
American Samoa AS
Bosnia and Herzegovina BA
Burkina Faso BF
Brunei Darussalam BN

Пояснение

  • a=$1 сохраняем первое значение во временномпеременная.
  • for (i=2; i<=NF; i++) $(i-1)=$i сохранить значение N-го поля в (N-1) -ом поле.
  • $NF=a сохранить первое значение ($1) в последнем поле.
  • {}1 истинное условие для awk выполнения действия по умолчанию: {print $0}.

Таким образом, если у вас есть другой разделитель полей, результаттоже хорошо:

$ cat c
AE-United-Arab-Emirates
AG-Antigua-&-Barbuda
AN-Netherlands-Antilles
AS-American-Samoa
BA-Bosnia-and-Herzegovina
BF-Burkina-Faso
BN-Brunei-Darussalam

$ awk 'BEGIN{OFS=FS="-"}{a=$1; for (i=2; i<=NF; i++) $(i-1)=$i; $NF=a}1' c
United-Arab-Emirates-AE
Antigua-&-Barbuda-AG
Netherlands-Antilles-AN
American-Samoa-AS
Bosnia-and-Herzegovina-BA
Burkina-Faso-BF
Brunei-Darussalam-BN
2 голосов
/ 17 ноября 2010

awk '{ tmp = $1; sub(/^[^ ]+ +/, ""); print $0, tmp }'

2 голосов
/ 16 ноября 2010

Разделитель полей в gawk (как минимум) может быть как строкой, так и символом (это также может быть регулярное выражение). Если ваши данные соответствуют, то это будет работать:

awk -F "  " '{print $2,$1}' inputfile

Это два пробела между двойными кавычками.

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