#awk
#awk
Вопрос:
Мой входной файл: ( дублированный UUID (например: WW000001
), указанный как в HBA0, так и в HBA1, и оба они имеют уникальное имя, например: /dev/sda
и /dev/sde
)
/dev/sda HBA0 WW000001
/dev/sdb HBA0 WW000002
/dev/sdc HBA0 WW000003
/dev/sdd HBA0 WW000004
/dev/sde HBA1 WW000001
/dev/sdf HBA1 WW000002
/dev/sdg HBA1 WW000003
/dev/sdh HBA1 WW000004
Тот же UUID (например: /dev/sda
и /dev/sde
) означает фактически тот же диск, но с другим именем диска и путем HBA.
Я хочу получить сбалансированный список (уникальный UUID, указанный сбалансированным в HBA0
и HBA1
). Последовательность не имеет значения, если UUID уникален в конечном результате, а у HBA0
и HBA1
одинаковые номера дисков.
пример:
/dev/sda HBA0 WW000001
/dev/sdb HBA0 WW000002
/dev/sdg HBA1 WW000003
/dev/sdh HBA1 WW000004
наконец, я получу сбалансированный список:
/dev/sda
/dev/sdb
/dev/sdg
/dev/dfh
Комментарии:
1. Не могли бы вы подробнее рассказать о логике того, как диски
/dev/sda
и/dev/sde
одинаковы?2. В MPIO они одинаковы, когда UUID одинаковый.
3. Таким образом, это означает, что либо
/dev/sdc
печатается, либо/dev/sdg
печатается, для вас это не имеет значения? (Я не верю), извините, просто пытаюсь понять логику, с помощью которой вы хотите напечатать строки.4. да, это имеет значение, поскольку их HBA отличается.
Ответ №1:
Не могли бы вы попробовать следующее:
awk '{
dev[$2,$3] = $1 # make device list indexed by HBA and UUID
uuid[$3] # make UUID list
}
END {
j = 0 # reset HBA number
for (i in uuid) { # loop over UUID list
hba = "HBA" j # "HBA0" or "HBA1"
print dev[hba,i], hba, i # print the list
j = xor(j, 1) # flip between "0" and "1"
}
}' inputfile
Результат:
/dev/sda HBA0 WW000001
/dev/sdf HBA1 WW000002
/dev/sdc HBA0 WW000003
/dev/sdh HBA1 WW000004
Чтобы получить balanced
список, он изменяет значение HBA
между HBA0
и HBA1
один за другим.
Последовательность устройств отличается от опубликованного примера, но я надеюсь, что она будет соответствовать вашим требованиям.
Ответ №2:
Вы можете либо отсортировать свой файл, если он не отсортирован, а затем использовать комбинацию head
, tail
, и wc
, чтобы выбрать сбалансированные (четное количество) строк из начала и конца вашего файла, например
$ head -n$(($(wc -l < file) / 4)) file; tail -n$(($(wc -l < file) / 4)) file
/dev/sda HBA0 WW000001
/dev/sdb HBA0 WW000002
/dev/sdg HBA1 WW000003
/dev/sdh HBA1 WW000004
По сути, поскольку ваш файл состоит из двух половин, из которых вы хотите получить первую и последнюю четверть строк, above wc
используется для подсчета общего количества строк, а затем вывода первой и последней четверти. Для этого требуется несколько подоболочек, поэтому, если у вас миллион записей, awk
это был бы лучший выбор, но всегда есть более одного способа скрыть кошку…
Если вам нужно сначала отсортировать, то sort -k1,8 file
это будет сделано, и поскольку вы отметили свой вопрос [bash]
, вы можете просто использовать замену процесса для final file
в каждой из двух команд, например < <(sort -k1,8 file)
.
Чтобы получить окончательный список, просто выберите первое поле с cut
помощью, например
$ cut -d' ' -f1 < <(head -n$(($(wc -l < file) / 4)) file; tail -n$(($(wc -l < file) / 4)) file)
/dev/sda
/dev/sdb
/dev/sdg
/dev/sdh