обработка текста (чтение и вычисление из двух файлов) [awk, скрипт]

Есть другой способ: вы можете создать пункт меню, который сообщает 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; он просто использует вторую конфигурацию.

1
14.10.2016, 16:10
3 ответа

TXR Lisp с макросом awk :

(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 ).

0
27.01.2020, 23:35
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
1
27.01.2020, 23:35

Это действительно довольно сложно. Я бы посоветовал создать сценарий 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 , очевидно, не работает). Вероятно, вы можете заставить его обрабатывать больше случаев (например, если у вас есть одно и то же значение несколько раз в вашем векторе ...), но я оставлю это вам, поскольку теперь у вас есть отправная точка!

1
27.01.2020, 23:35

Теги

Похожие вопросы