awk :Анализ текстового файла с использованием ключевых слов для макета

В настоящее время рекомендуемым решением для интеграции современных Linux в AD обычно является использование sssd.

Это есть в официальной документации Ubuntu 18.04.

Убедитесь, что установлены необходимые пакеты:

sudo apt install krb5-user samba sssd chrony

Установка krb5-userзапросит три вещи, используя для них общие имена Kerberos:

  • имя области :при работе с AD это имя домена AD в ЗАГЛАВНОМ РЕГИСТРЕ.
  • имя сервера KDC :это одно из заданий контроллера домена AD.
  • имя административного сервера Kerberos :это также контроллер домена AD.

Поскольку аутентификация Active Directory основана на протоколе Kerberos, требуется, чтобы системные часы были достаточно синхронизированы с часами серверов AD. Обычно серверы AD предоставляют для этой цели службу NTP. Если вы используете chronyдля синхронизации времени,добавьте имя вашего (ближайшего )контроллера домена AD также в/etc/chrony/chrony.conf:

server my.ad.domain.controller.example

Samba необходима для выполнения некоторых служб, связанных с аутентификацией AD, даже если вы не используете какие-либо каталоги Linux совместно с системами Windows. Добавьте это в раздел [global]документа /etc/samba/smb.conf:

.

[global]

workgroup = SHORT_NAME_OF_AD_DOMAIN
client signing = yes
client use spnego = yes
kerberos method = secrets and keytab
realm = AD.DOMAIN.FULL.NAME
security = ads

Замените SHORT_NAME_OF_AD_DOMAINи AD.DOMAIN.FULL.NAMEсоответствующим образом.

Создайте файл конфигурации SSSD/etc/sssd/sssd.conf:

[sssd]
services = nss, pam
config_file_version = 2
domains = AD.DOMAIN.FULL.NAME

[domain/AD.DOMAIN.FULL.NAME]
id_provider = ad
access_provider = ad

# Use this if users are being logged in at /.
# This example specifies /home/DOMAIN-FQDN/user as $HOME.  Use with pam_mkhomedir.so
override_homedir = /home/%d/%u

# Uncomment if the client machine hostname doesn't match the computer object on the DC.
# ad_hostname = mymachine.ad.domain.full.name
# Uncomment if DNS SRV resolution is not working
# ad_server = dc.ad.domain.full.name

# Uncomment if the AD domain is named differently than the Samba domain
# ad_domain = AD.DOMAIN.FULL.NAME

# Enumeration is discouraged for performance reasons.
# enumerate = true

Этот файл необходимо защитить, чтобы только root мог получить к нему доступ, иначе sssdоткажется запускаться:

sudo chown root:root /etc/sssd/sssd.conf
sudo chmod 600 /etc/sssd/sssd.conf

Убедитесь, что система всегда знает свое полное -квалифицированное DNS-имя домена; при необходимости добавьте его в /etc/hosts.

Затем перезапустите службы, конфигурация которых была изменена:

sudo systemctl restart chrony.service
sudo systemctl restart smbd.service nmbd.service 
sudo systemctl start sssd.service

Теперь вы уже должны иметь возможность использовать kinitдля выполнения начальной аутентификации Kerberos с помощью AD. Сделайте это как root, используя учетную запись пользователя AD, которая имеет необходимые разрешения для добавления новых систем в домен :

.

sudo kinit Administrator

Убедитесь, что вы действительно получили билет аутентификации Kerberos:

sudo klist

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

sudo net ads join -k

Если эта команда выполнена успешно, теперь вы сможете запрашивать информацию об учетных записях пользователей AD с помощью команд Linux:

getent passwd some-AD-username

Поскольку новые пользователи могут быть добавлены в AD в любое время, вам необходимо настроить механизм, который будет автоматически -создавать домашний каталог для любого пользователя AD при входе в систему, если он еще не существует. Добавьте эту строку в /etc/pam.d/common-session, сразу после строки session required pam_unix.so...:

.

session    required    pam_mkhomedir.so skel=/etc/skel/ umask=0022

Строка override_homedirв sssd.confопределяет пути к домашним каталогам пользователей AD.

1
19.04.2021, 21:41
2 ответа

Использование Perl:

#!/usr/bin/perl

# @keys is an array containing the keywords. It also determines
# the field output order.  This can be read from a file if needed,
# but here it's hard-coded.
my @keys = qw(ALBERT BRYAN CLAUDIA DAVID ERIK);

# create and pre-compile a regex matching all the keywords
my $keys = join("|",@keys);
my $keys_re = qr/$keys/;

# make an empty hash containing elements for all the keys so that
# we can start processing each input record afresh, with a fully
# populated list of keys.
my %empty = map +( $_ => '' ), @keys;


# main loop, process stdin and/or filename args
while(<>) {
  # clean up the input a little.
  chomp;            # trim newlines at EOL
  s/^\s*|\s*$//g;   # trim leading and trailing whitespace

  # ignore empty lines.
  next if (m/^$/);

  # NUL can't be in text input, so insert it as a marker around
  # the keywords. i.e. insert NULs before and after each keyword
  s/$keys_re/\000$&\000/g;

  # split the input record on NUL, trimming spaces and discarding
  # the first element (a bogus artificial field which only exists
  # as a side-effect of inserting a NUL before the first keyword.)
  my (undef,@record) = split /\s*\000\s*/;

  # pre-populate the fields hash for each record.
  my %fields = %empty;

  # now insert the real values for each keyword if they exist.
  foreach my $i (0..$#record) {
    $fields{$record[$i]} = $record[$i+1];
    $i++;
  };

  print join(";", map +( $fields{$_} ), @keys),"\n";
}

Если вам нужен пробел после каждого двоеточия с запятой -, измените строку print join(";",...)выше и добавьте один.

Чтобы прочитать ключевые слова из файла, замените строку my @keys = qw(...)выше на:

# slurp in the keywords file and split it on any whitespace.
my @keys = split /\s+/, do {
  local $/;   # read entire file at once - slurp
  my $fname = 'keywords.txt';
  open(my $fh, '<', $fname) or die "Error opening $fname: $!";
  <$fh>
};

keywords.txt может содержать ключи, разделенные любой комбинацией вертикальных или горизонтальных пробелов -пробелов, табуляций, новых строк, CR/LF и т. д., например.

$ cat keywords.txt 
ALBERT
BRYAN   CLAUDIA
DAVID ERIK

Сохранить как, например. iterate.plи сделайте его исполняемым с помощью chmod +x iterate.pl.

$./iterate.pl input.txt 
some a;some b;some c;some d;some e
some a;some b;;;some e
some a;some b;;some d;

Если вам нужен более красивый вывод для просмотра в меньшем или любом другом формате, вы можете использовать column, например.

$./iterate.pl input.txt | column -s';' -o'; ' -t
some a; some b; some c; some d; some e
some a; some b;       ;       ; some e
some a; some b;       ; some d; 
0
28.04.2021, 22:52

Предполагая, что некоторые теги (имена, такие как "ALBERT" ), могут отсутствовать в первой строке точно так же, как они могут отсутствовать в других строках, вам потребуется двухпроходный -подход, чтобы сначала идентифицировать все теги. теги, а затем вывести значения для всех из них для каждой строки, независимо от того, присутствуют они в этой строке или нет.

$ cat tst.awk
BEGIN { OFS=";" }
NR==FNR {
    for (i=1; i<NF; i+=3 ) {
        if ( !seen[$i]++ ) {
            tags[++numTags] = $i
        }
    }
    next
}
{
    delete tag2val
    for (i=1; i<NF; i+=3) {
        tag = $i
        val = $(i+1) FS $(i+2)
        tag2val[tag] = val
    }

    for (tagNr=1; tagNr<=numTags; tagNr++) {
        tag = tags[tagNr]
        val = tag2val[tag]
        printf "%s%s", val, (tagNr<numTags ? OFS : ORS)
    }
}

$ awk -f tst.awk example.txt example.txt | column -t -s';' -o'; '
some a; some b; some c; some d; some e
some a; some b;       ;       ; some e
some a; some b;       ; some d;

Приведенный выше код выводит для каждой строки значения всех тегов в том порядке, в котором они появлялись во всех входных данных.

Если вы хотите видеть теги как заголовки столбцов:

$ cat tst.awk
BEGIN { OFS=";" }
NR==FNR {
    for (i=1; i<NF; i+=3 ) {
        if ( !seen[$i]++ ) {
            tags[++numTags] = $i
        }
    }
    next
}
FNR==1 {
    for (tagNr=1; tagNr<=numTags; tagNr++) {
        tag = tags[tagNr]
        printf "%s%s", tag, (tagNr<numTags ? OFS : ORS)
    }
}
{
    delete tag2val
    for (i=1; i<NF; i+=3) {
        tag = $i
        val = $(i+1) FS $(i+2)
        tag2val[tag] = val
    }

    for (tagNr=1; tagNr<=numTags; tagNr++) {
        tag = tags[tagNr]
        val = tag2val[tag]
        printf "%s%s", val, (tagNr<numTags ? OFS : ORS)
    }
}

$ awk -f tst.awk example.txt example.txt | column -t -s';' -o'; '
ALBERT; BRYAN ; CLAUDIA; DAVID ; ERIK
some a; some b; some c ; some d; some e
some a; some b;        ;       ; some e
some a; some b;        ; some d;
1
28.04.2021, 22:52

Теги

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