Есть другой способ: вы можете создать пункт меню, который сообщает GRUB загрузить другой вторичный файл grub.cfg, например, из другого дистрибутива Linux.
Например, я начал с Gentoo Linux, из которого я установил GRUB2 в MBR (машина слишком старая для EFI).
Затем я установил NixOS, который настроил для создания grub.cfg в собственном / boot (отдельно от Gentoo / boot ), но без установки GRUB .
Чтобы уточнить, grub-install
был выполнен из Gentoo, но не из NixOS.
Затем, чтобы иметь возможность загружать NixOS, я добавил это в /etc/grub.d/40_custom в Gentoo:
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
menuentry 'NixOS' --class gnu-linux --class gnu --class os $menuentry_id_option 'nixos-0aca58bc-8fdb-4a07-aa2f-56406bcf19b7' {
set root='hd0,msdos4'
configfile /nixos/root/boot/grub/grub.cfg
}
Ключ - это файл конфигурации / nixos / root / boot Строка /grub/grub.cfg
. Он сообщает GRUB загрузить еще один файл grub.cfg. Затем я запустил grub-mkconfig
из Gentoo, чтобы применить изменения.
Теперь, когда я загружаюсь и выбираю NixOS , весь интерфейс GRUB обновляется, чтобы отразить NixOS grub.cfg, из которого я могу загрузить ОС. В отличие от цепной загрузки, эта конфигурация использует одну установку GRUB; он просто использует вторую конфигурацию.
(let ((h (hash :equal-based)))
(awk (:inputs "word-dom-pairs")
(t (inc [h [f 0] 0])))
(awk (:inputs "word-vectors")
(t (whenlet ((count [h [f 0]]))
(fconv - : r)
(let* ((n-fn-pairs (zip (rest f) (range 2)))
(n-fn-sorted [sort n-fn-pairs > first]))
(each ((p [n-fn-sorted 0..count]))
(prn [f 0] (second p) (first p))))))))
Выполнить:
$ txr munge.tl
bank 4 3.2
bank 3 1.5
bank 2 0.9
God 3 2.1
Данные:
$ cat word-dom-pairs
car transport
car machine
bank economy
bank politics
bank parks
God religion
$ cat word-vectors
bank 0.9 1.5 3.2 -0.2 0.1
God 1.0 2.1 -0.5 0.7
rose 0.2 -1.8
Вот версия программы, свернутой в одно выражение awk
:
(awk (:inputs "word-dom-pairs" "word-vectors")
(:let (h (hash :equal-based)))
((= arg 1) (inc [h [f 0] 0]))
((= arg 2) (whenlet ((count [h [f 0]]))
(fconv - : r)
(let* ((n-fn-pairs (zip (rest f) (range 2)))
(n-fn-sorted [sort n-fn-pairs > first]))
(each ((p [n-fn-sorted 0..count]))
(prn [f 0] (second p) (first p)))))))
Два : input
из ранее отдельных awk
-ов объединяются в один. {{1 }} Мы заменяем безусловно истинные шаблоны t
селекторами, в зависимости от того, какой ввод обрабатывается, заданный переменной arg
. let
, который связывает переменную хеш-таблицы, сворачивается в предложение макроса awk : let
.
Если мы удалим предложение (: inputs ...)
, мы сможем передать файлы, используя пару аргументов командной строки:
$ txr munge.tl file1 file2
TXR Lisp - это типобезопасный динамический язык, в котором переменные должны быть определены перед назначением или использованием. Несуществующие переменные и ненужные строки не являются числовым нулем, а строки, которые выглядят как числа, не являются этими числами. Вот почему мы явно определяем существование хэш-таблицы и используем fconv
для явного преобразования второго и последующих полей в действительные числа ( r
).
awk '
NR==FNR{ #operate matrix file first
A[$1] = 1 #array of words
for(i=2;i<=NF;i++)
B[$1 OFS i] = $i #array with indexes [word field_num]
next
}
$1 in A{ #if word in array A
max = $1 OFS 2
for(i in B)
if(i ~ "^" $1 && B[max] < B[i])
max = i #find maximum in B-array
print max, B[max] #output word + field_num + value
delete B[max] #exclude value from next search
}
}
' matrix list
Если версия awk допускает псевдо-многомерные массивы, сценарий может быть упрощен
awk '
NR==FNR{
for(i=2;i<=NF;i++)
A[$1][i] = $i
next
}
$1 in A{
max = 2
for(i in A[$1])
if(A[$1][max] < A[$1][i])
max = i
print $1, max, A[$1][max]
delete A[$1][max]
}
}
' matrix list
Это действительно довольно сложно. Я бы посоветовал создать сценарий awk
, если только кто-нибудь не придумает чудо-однострочник.
Внутри вашего файла awk
:
NR==FNR {
a[$1]++
next
} #Your probably know what that does since it's your starting point
# If first field is a key in array a
$1 in a {
# Assign the number of occurences of this word in variable n
n=a[$1]
# Initialize this value to + INFINITY
k=-log(0)
# Loop on the number of occurences of the word
for (i=0; i<n; i++) {
# Initialize max value and its index at the first value of the vector
m=$2
i_m=2
# Loop on the number of fields in the matrix for that word
for (j=3; j<NF+1; j++) {
# Look for the largest value that stays below previous max (if none then k is INFINITY)
if ($j > m && $j < k) { m=$j; i_m=j }
}
# Print the word, the index of its max and its value
printf $1" "i_m" "m"\n"
# Store the max to be able to scan for the next biggest number at next iteration
k=m
}
}
Для его запуска:
$ awk -f myScript.awk list matrix
Мой скрипт работает нормально, за исключением одного случая: если в встречается такое же или большее количество слов. ] list
, чем есть значения в его векторе в матрице
. Это не похоже на проблему, поскольку ваши векторы довольно большие. Также инициализация k
в -log (0)
, чтобы получить значение inf
, немного странно, но я не мог понять, как его установить к inf
напрямую ( = inf
, очевидно, не работает). Вероятно, вы можете заставить его обрабатывать больше случаев (например, если у вас есть одно и то же значение несколько раз в вашем векторе ...), но я оставлю это вам, поскольку теперь у вас есть отправная точка!