Объясните удаление этой повторяющейся строки, сохранение порядка, однострочный AWK

Я узнал очень удобный способ удалить повторяющиеся строки, сохраняя порядок изУдалить дубликаты без сортировки файлов - BASH.

Скажем, если у вас есть следующий файл,

$cat file
a
a
b
b
a
c

Вы можете использовать следующее, чтобы удалить дубликаты строк:

$awk '!x[$1]++' file
a
b
c

Как это работает с точки зрения приоритета операций?

 Alby04 июн. 2012 г., 20:48
@brandizzi извините за задержку! Я обычно жду 3 ~ 5 дней, чтобы выбрать лучший ответ
 Oliver01 июн. 2012 г., 00:36
Я не понимаю вопроса? Удаляет дубликаты строк. Какой приоритет вы имеете в виду?
 Dennis Williamson01 июн. 2012 г., 02:08
@Oliver: приоритет оператора.
 brandizzi01 июн. 2012 г., 00:40
Просто примечание: он удалит не только дублированные строки, но иall lines with the same value at the first column, тоже! Добавить строку сd a а такжеd b в файл, и вы поймете, что я имею в виду. Чтобы удалить только дублированные строки, вы можете написать!x[$0]++, поскольку$0 возвращает всю строку, а не только первый столбец. Чтобы лучше это понять, смотрите ответ @larsmans.

Ответы на вопрос(2)

Решение Вопроса

Выражение разбирается как

!(x[$(1)]++)

Итак, изнутри, это:

Take field 1 of the current input line, $(1) (note that $ is an operator in AWK, unlike in Perl). Index x with the value of field 1; if x is an unbound variable, bind it to a new associative array. Post-increment x[$(1)]; a rule similar to the one in C applies, so the value of the expression is that of x[$(1)] prior to the increment, which will be zero if x[$(1)] has not yet been assigned a value. Negate the value of the previous, which will yield truth when x[$(1)] is zero. Actually do the increment so that x[$(1)] gets a non-zero value. So, the next time, x[$(1)] for the same value of $(1) will return 1.

Затем это выражение оценивается для каждой строки во входных данных и определяет, подразумевается ли подразумеваемое действие по умолчаниюawk должен быть выполнен, который должен повторить строкуstdout.

 01 июн. 2012 г., 00:55
@brandizzi: хорошая мысль, добавил это.
 01 июн. 2012 г., 00:47
Просто дополнение:!x[$1]++ является выражением, которое, если true, выполнит следующий блок кода. Тем не менее, он не имеет никакого блока кода; в этом случае поведение по умолчанию заключается в выполненииprint команда, которая печатает текущую строку, если ей не задан параметр. Это означает, что в этом случае!x[$1]++ эквивалентно!x[$1]++{print;}, Итак, в первой строке возвращается значение$(1), результат!x[$1]++ будет истинным, и строка будет распечатана; в следующий раз, однако,!x[$1]++ выдаст false, и строки не будут напечатаны.

поэтому первый столбец или первое поле каждой строки$1, используется в качестве индекса для массиваx.

Ваш ответ на вопрос