Переменная не принимается в awk при передаче из файла

Пока ответ:

sudo updatedb

технически правильно, почти никогда не рекомендуется запускать updatedbв командной строке отдельно, если также установлено задание cron. В зависимости от варианта Unix задание cron содержит положения блокировки и любой объем конфигурации, который не охватывается автономной командой updatedb.

Если базу данных локации необходимо часто обновлять, определенно стоит попытаться определить подходящее задание cron для конкретного хоста и запустить его вручную.

В зависимости от администратора задание cron для updatedbможет быть скрыто в разных местах. Таким образом, простая -попытка грубой силы найти задание cron будет:

( sudo crontab -l > /tmp/crontab.root;
  ( echo /tmp/crontab.root; ls -1d /etc/*cron* /etc/*cron*/* ) \
  | tr '\n' '\0' \
  | xargs -0 -r -e grep -nH -e updatedb;
  rm -f /tmp/crontab.root
) 2>/dev/null

, который показывает следующий результат на одной из моих систем Ubuntu:

/etc/cron.daily/mlocate:5:[ -x /usr/bin/updatedb.mlocate ] || exit 0
/etc/cron.daily/mlocate:21:flock --nonblock /run/mlocate.daily.lock $IONICE /usr/bin/updatedb.mlocate

Правильная команда для обновления базы данных locate в этом случае

sudo /etc/cron.daily/mlocate

Более систематический подход заключается в определении пакета, который предоставляет locateи updatedb.

Например, в ОС с пакетом apt/dpkg вы можете узнать, какой вариант locate установлен с помощью:

dpkg -S locate | grep /bin/

В моем случае это:

mlocate: /usr/bin/updatedb.mlocate

Чтобы узнать, какое задание cron отвечает за это, запустите:

dpkg -L mlocate | grep cron

Что в моем случае показывает:

/etc/cron.daily
/etc/cron.daily/mlocate

Чтобы обновить базу данных, запустите задание cron от имени пользователя root:

sudo /etc/cron.daily/mlocate

Если cronjob отсутствует, а updateb сам по себе не работает, попробуйте найти установленную версию с помощью:

dpkg -L mlocate | grep /bin/

, который возвращает:

/usr/bin/mlocate
/usr/bin/updatedb.mlocate

NB :Если вы понизите этот ответ, будьте так любезны и дайте мне знать, почему ответ любителя считается лучшим.

3
24.10.2021, 06:12
1 ответ

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

Использование любого awk в любой оболочке на каждом компьютере Unix:

$ cat tst.awk
NR==FNR {
    tgts[$0]
    next
}
$0 in tgts {
    if ( $0 != prevTgt ) {
        print $0
        prevTgt = $0
    }
    print prevLine
}
{ prevLine = $1 FS $2 }

$ awk -f tst.awk targets file
box_name: AIX_RUN_WATCH
insert_job: AIXstop
insert_job: AIX_start

Оригинальный ответ:

awk '
    BEGIN { RS=""; FS="\n" }
    $2 != prev {
        print $2
        prev = $2
    }
    { print $1 }
' file
ght: ertyjk
xxx: rtyuiol
xxx: ertyuikl_fghjk
xxx: qwertyujkl
xxx: rtyuiol_123
ght: YUIOPO
xxx: rtyuiol
xxx: rtyuiopfghj
xxx: dfghjkvbnm
xxx: qzdfghnbvfgh
xxx: qsxcvghuiokmnhgf

См.https://www.gnu.org/software/gawk/manual/gawk.html#Multiple-Lineо том, как установка RS на null позволяет нам работать с многострочными -записями, а затем установка FS на новую строку означает, что каждое поле в такой записи представляет собой целую строку, поэтому мы обрабатываем ваши данные как пустые -записи, разделенные строками, каждая из которых содержит 2 строки данных.

Вы упомянули, что у вас есть какой-то другой файл со строками, который указывает, какие строки следует печатать, подразумевая, что есть и другие блоки, которые не следует печатать. Если у вас есть такой файл и он выглядит так:

$ cat targets
ght: ertyjk
ght: YUIOPO

, а другой ваш входной файл содержит несколько строк ght:, которые не соответствуют приведенным выше, например. см. блоки ght: whateverв модифицированном входном файле ниже:

$ cat file
xxx: rtyuiol
ght: ertyjk

xxx: ertyuikl_fghjk
ght: ertyjk

xxx: qwertyujkl
ght: ertyjk

xxx: rtyuiol_123
ght: ertyjk

xxx: foo
ght: whatever

xxx: bar
ght: whatever

xxx: rtyuiol
ght: YUIOPO

xxx: rtyuiopfghj
ght: YUIOPO

xxx: dfghjkvbnm
ght: YUIOPO

xxx: qzdfghnbvfgh
ght: YUIOPO

xxx: qsxcvghuiokmnhgf
ght: YUIOPO

, тогда приведенный выше код будет обновлен до:

awk '
    BEGIN { FS="\n" }
    NR==FNR {
        tgts[$0]
        next
    }
    $2 != prev {
        if ( inTgts = ($2 in tgts) ) {
            print $2
        }
        prev = $2
    }
    inTgts { print $1 }
' targets RS='' file
ght: ertyjk
xxx: rtyuiol
xxx: ertyuikl_fghjk
xxx: qwertyujkl
xxx: rtyuiol_123
ght: YUIOPO
xxx: rtyuiol
xxx: rtyuiopfghj
xxx: dfghjkvbnm
xxx: qzdfghnbvfgh
xxx: qsxcvghuiokmnhgf
2
25.10.2021, 13:23

Теги

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