У меня есть файл, который выглядит так:
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»?
Ответы:
Назначение
$1
работает, но останется ведущее место:awk '{first = $1; $1 = ""; print $0, first; }'
Вы также можете найти количество столбцов
NF
и использовать его в цикле.источник
awk {'first = $1; $1=""; print $0'}|sed 's/^ //g'
$1=""
оставляет пробел, как упомянул Бен Джексон, поэтому используйтеfor
цикл:Итак, если ваша строка была «один, два, три», вывод будет следующим:
два
три
Если вы хотите, чтобы результат был в одной строке, вы можете сделать следующее:
Это даст вам: «два три»
источник
awk '{for(i=2;i<=NF;i++){ printf("%s",( (i>2) ? OFS : "" ) $i) } ; print ;}'
which: напечатать поля 2 в NF, добавить разделитель выходных полей по мере необходимости (т. е. кроме $ 2). Последняя печать добавляет последнюю строку, чтобы завершить печать текущей строки. Этот будет работать, если вы измените FS / OFS (т.е. он не всегда будет «пробелом»)Используйте
cut
команду с--complement
опцией:источник
echo a b c | cut -d' ' -f 2-
является альтернативойМожет быть, самый лаконичный способ:
Пояснение:
$(NF+1)=$1
: Генератор "нового" последнего поля.$1=""
: Установить для исходного первого поля значение nullsub(FS,"")
: После первых двух действий{$(NF+1)=$1;$1=""}
избавьтесь от первого разделителя полей с помощью sub. Окончательный отпечаток неявный.источник
Удалите первое поле и разделитель и распечатайте результат (
7
это ненулевое значение, поэтому выводится $ 0).источник
1
? Мне интересно использование этого шаблона и я хотел понять это. Спасибо!Если задать для первого поля значение,
""
останется одна копияOFS
в начале$0
. Предполагая, чтоOFS
это только один символ (по умолчанию это один пробел), мы можем удалить его с помощьюsubstr($0, 2)
. Затем мы добавляем сохраненную копию$1
.источник
Если вы открыты для решения Perl ...
представляет собой простое решение с разделителем ввода / вывода из одного пробела, которое дает:
Следующий немного сложнее
и предполагает, что разделитель ввода / вывода состоит из двух пробелов:
Используются следующие параметры командной строки:
-n
цикл вокруг каждой строки входного файла, не печатать автоматически каждую строку-l
удаляет символы новой строки перед обработкой и добавляет их после-a
режим autosplit - разбивать входные строки в массив @F. По умолчанию разделение на пробелы-F
модификатор autosplit, в этом примере разбивается на '' (два пробела)-e
выполнить следующий код Perl@F
- это массив слов в каждой строке, индексируемый, начиная с 0$#F
- это количество слов в@F
@F[1..$#F]
- это фрагмент массива от элемента 1 до последнего элемента@F[1..$#F,0]
- это фрагмент массива от элемента 1 до последнего элемента плюс элемент 0источник
Разделителем полей в gawk (по крайней мере) может быть строка, а также символ (это также может быть регулярное выражение). Если ваши данные согласованы, то это будет работать:
Это два пробела между двойными кавычками.
источник
awk '{ tmp = $1; sub(/^[^ ]+ +/, ""); print $0, tmp }'
источник
Переместим все записи в следующую и сделаем последнюю первой:
Объяснение
a=$1
сохранить первое значение во временную переменную.for (i=2; i<=NF; i++) $(i-1)=$i
сохранить значение N-го поля в (N-1) -ое поле.$NF=a
сохранить первое значение ($1
) в последнее поле.{}1
истинное состояние , чтобы сделатьawk
действие по умолчанию:{print $0}
.Таким образом, если у вас есть другой разделитель полей, результат также будет хорошим:
источник
Первый удар, похоже, сработает в вашем конкретном случае.
источник
Опция 1
Есть решение, которое работает с некоторыми версиями awk:
Пояснение:
Результат:
Однако в старых версиях awk это может не получиться.
Вариант 2
То есть:
Обратите внимание, что необходимо стереть OFS, а не FS. При присвоении поля $ 1 строка пересчитывается. Это меняет все прогоны FS на один OFS.
Но даже этот вариант по-прежнему не работает с несколькими разделителями, что ясно показывает изменение OFS:
Эта строка выведет:
Это показывает, что запуски FS заменяются одним OFS.
Единственный способ избежать этого - избежать повторного расчета поля.
Одна функция, которая может избежать повторного вычисления, - это sub.
Первое поле может быть захвачено, затем удалено из $ 0 с помощью sub, а затем оба поля распечатаны повторно.
Вариант 3
Даже если мы изменим FS, OFS и / или добавим больше разделителей, это работает.
Если входной файл изменен на:
И команда изменится на:
Вывод будет (с сохранением разделителей):
Команду можно расширить до нескольких полей, но только с современными awks и с активной опцией --re-interval. Эта команда в исходном файле:
Выведет это:
источник
Если вы открыты для другого решения Perl:
источник
Также есть опция sed ...
Разъяснил ...
Более подробно объяснил ...
источник
Еще один способ ...
... это объединяет поля от 2 до NF с FS и выводит по одной строке на строку ввода
Я использую это с git, чтобы увидеть, какие файлы были изменены в моем рабочем каталоге:
источник
Другой и простой способ использования команды cat
источник