Создание CSV из текстовых файлов с помощью sed или awk

Вы правы, и openstack keypair create, иssh-keygenмогут (, но обратите внимание, что :не обязательно нужно)создать пару ключей, которую может понять opensh -совместимый ssh-сервер.

Они генерируются по-разному, поскольку клиент openstack написан на Python, а openssh — на C. Однако, учитывая пару ключей, я не думаю, что можно было бы определить, был ли он сгенерирован openstack или ssh -кейген.Другими словами, хотя вы не можете сказать, что они «совершенно одинаковы», вы также не можете сказать, что они различны в каком-либо осмысленном смысле.

При использовании openstack keypair create --public-key <file>предполагается, что вы хотите сделать открытый ключ доступным в рамках вашего поставщика облачных услуг для внедрения в виртуальную машину. Это полезно только в том случае, если у вас уже есть доступ к закрытому ключу. Вы можете использовать эту возможность, если у вас уже есть закрытый ключ, сгенерированный, скажем, ssh-keygen, и вы хотите использовать этот ключ для ssh к виртуальной машине.

0
30.01.2021, 18:24
3 ответа

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

$ cat tst.awk
BEGIN {
    numKeys = split("foo bar", tmp)
    for (i in tmp) {
        keys[i] = tmp[i]
    }
    FS=":"; OFS=","
}
{ fnameKey2val[FILENAME,$1] = $2 }
END {
    printf "%s%s", "name", OFS
    for (keyNr=1; keyNr<=numKeys; keyNr++) {
        key = keys[keyNr]
        printf "%s%s", key, (keyNr<numKeys ? OFS : ORS)
    }

    for (fileNr=1; fileNr<ARGC; fileNr++) {
        fname = ARGV[fileNr]
        printf "%s%s", fname, OFS
        for (keyNr=1; keyNr<=numKeys; keyNr++) {
            key = keys[keyNr]
            val = (fnameKey2val[fname,key] == "" ? "no" : fnameKey2val[fname,key])
            printf "%s%s", val, (keyNr<numKeys ? OFS : ORS)
        }
    }
}

или если вы НЕ хотите печатать столбец для ключа, если он отсутствует во всех файлах:

$ cat tst.awk
BEGIN {
    split("foo bar", tmp)
    for (i in tmp) {
        targets[tmp[i]]
    }
    FS=":"; OFS=","
}
!($1 in targets) { next }
!seen[$1]++ { keys[++numKeys] = $1 }
{ fnameKey2val[FILENAME,$1] = $2 }
END {
    printf "%s%s", "name", OFS
    for (keyNr=1; keyNr<=numKeys; keyNr++) {
        key = keys[keyNr]
        printf "%s%s", key, (keyNr<numKeys ? OFS : ORS)
    }

    for (fileNr=1; fileNr<ARGC; fileNr++) {
        fname = ARGV[fileNr]
        printf "%s%s", fname, OFS
        for (keyNr=1; keyNr<=numKeys; keyNr++) {
            key = keys[keyNr]
            val = (fnameKey2val[fname,key] == "" ? "no" : fnameKey2val[fname,key])
            printf "%s%s", val, (keyNr<numKeys ? OFS : ORS)
        }
    }
}

Они оба будут давать один и тот же результат из данного выборочного ввода:

$ awk -f tst.awk *.txt
name,foo,bar
a.txt,yes,no
b.txt,no,yes
c.txt,no,no
3
18.03.2021, 22:33

Другим awkподходом может быть:

gawk -F':' -v OFS=',' '
BEGIN{ print "name", "foo", "bar"; };
    $2== ""    { $2="no"; };
    $1== "foo" { hold[FILENAME][1]= $2; };
    $1== "bar" { hold[FILENAME][2]= $2; };
END{ for (x in hold) print x, hold[x][1], hold[x][2]; }
' [abc].txt

Выход:

name,foo,bar
c.txt,no,no
a.txt,yes,no
b.txt,no,yes
1
18.03.2021, 22:33

перл-метод:

perl -lne '
  BEGIN {
    @A = qw(foo bar);
    @{$h{$_}}{@A} = qw(no) x @A for @ARGV;
  }
  /^(foo|bar)(:.*|$)/ and 
    ($h{$ARGV}{$1} = length($2)<2?"no":$2) =~ s/^://;
  }{$,=",";
  print q(name), @A;
  print $_, @{$h{$_}}{@A} for sort keys %h;
' -- *.txt
name,foo,bar
a.txt,yes,no
b.txt,no,yes
c.txt,no,no

Другой метод, использующий конвейеры grep -sort -sed и предполагающий существование foo/bar в файле

echo 'name,foo, bar'
grep -HE '^(foo|bar)(:|$)' *.txt |
sed -e '/:.*:/!s/$/:no/' |
sort -t: -k1,1 -k2,2r |
sed -Ee 'N;s/\n[^:]+:/:/;y/:/,/' |
cut -d, -f1,3,5
0
18.03.2021, 22:33

Теги

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