awk 'uniq' для ряда столбцов - PullRequest
0 голосов
/ 01 октября 2019

Я пытаюсь отфильтровать все дубликаты списка, игнорируя первые n столбцов, предпочтительно с помощью awk (но открыть для других реализаций)

Я нашел решение для фиксированного числа столбцов, но так как я не знаю, сколько будет столбцов, мне нужен диапазон. Это решение, которое я нашел здесь

Для ясности: я пытаюсь добиться псевдонима для history, который отфильтровывает дубликаты, но оставляет history_id без изменений, желательно безвозиться с заказом. История имеет вид

ID    DATE       HOUR     command
 5612  2019-07-25 11:58:30 ls /var/log/schaubroeck/audit/2019/May/
 5613  2019-07-25 12:00:22 ls /var/log/schaubroeck/         
 5614  2019-07-25 12:11:30 ls /etc/logrotate.d/                       
 5615  2019-07-25 12:11:35 cat /etc/logrotate.d/samba     
 5616  2019-07-25 12:11:49 cat /etc/logrotate.d/named 

Так что эта команда работает для команд длиной до четырех аргументов, но мне нужно заменить фиксированные столбцы диапазоном для учета всех случаев:

history | awk -F "[ ]" '!keep[$4 $5 $6 $7]++'

Я чувствую, что @kvantour выводит меня на правильный путь, поэтому я попытался:

history | awk '{t=$0;$1=$2=$3=$4="";k=$0;$0=t}_[k]++' | grep cd

Но это все равно дает повторяющиеся строки

 1102  2017-10-27 09:05:07 cd /tmp/
 1109  2017-10-27 09:07:03 cd /tmp/
 1112  2017-10-27 09:07:15 cd nagent-rhel_64/
 1124  2017-11-07 16:38:50 cd /etc/init.d/
 1127  2017-12-29 11:13:26 cd /tmp/
 1144  2018-06-21 13:04:26 cd /etc/init.d/
 1161  2018-06-28 09:53:21 cd /etc/init.d/
 1169  2018-07-09 16:33:52 cd /var/log/
 1179  2018-07-10 15:54:32 cd /etc/init.d/

Ответы [ 2 ]

2 голосов
/ 02 октября 2019

вы можете использовать сортировку:

history | sort -u -k4
  • -u для уникального
  • -k4 для сортировки только по всем столбцам, начиная с четвертого.

Выполнение этого на

 1102  2017-10-27 09:05:07 cd /tmp/
 1109  2017-10-27 09:07:03 cd /tmp/
 1112  2017-10-27 09:07:15 cd nagent-rhel_64/
 1124  2017-11-07 16:38:50 cd /etc/init.d/
 1127  2017-12-29 11:13:26 cd /tmp/
 1144  2018-06-21 13:04:26 cd /etc/init.d/
 1161  2018-06-28 09:53:21 cd /etc/init.d/
 1169  2018-07-09 16:33:52 cd /var/log/
 1179  2018-07-10 15:54:32 cd /etc/init.d/

дает:

 1124  2017-11-07 16:38:50 cd /etc/init.d/                                                                                                                                                                         
 1112  2017-10-27 09:07:15 cd nagent-rhel_64/                                                                                                                                                                      
 1102  2017-10-27 09:05:07 cd /tmp/                                                                                                                                                                                
 1169  2018-07-09 16:33:52 cd /var/log/

РЕДАКТИРОВАТЬ если вы хотите сохранить порядок, вы можете применить второй вид:

history | sort -u -k4 | sort -n
2 голосов
/ 01 октября 2019

Команда, которую вы предлагаете, не будет работать так, как вы ожидаете. Представьте, что у вас есть две строки, такие как:

a b c d 12 13 1
x y z d 1 21 31

Обе строки будут считаться дубликатами в качестве ключа, используемый в массиве _ для обоих d12131.

Это, вероятно, то, чтоВы заинтересованы в:

$ history | awk '{t=$0;$1=$2=$3="";k=$0;$0=t}!_[k]++'

Здесь мы храним исходную запись в переменной t. Удалите первые три поля записи, присвоив ей пустые значения. Это переопределит запись $0 и сохранит ее в ключе k. Затем мы сбрасываем запись на значение t. Мы выполняем проверку с помощью ключа k, который теперь содержит все поля, кроме первого 3.

примечание: установка разделителя поля как -F" " не установит его в один пробел, но к любой последовательности пробелов (пробелы и табуляции). Это также поведение по умолчанию. Если вам нужен один пробел, добавьте -F"[ ]"

...