Частичное совпадение строк в Awk

Спецификация формата %*sиспользует два аргумента, как и в C, один для ширины заполнения и один для строки, которая должна быть дополнена.

Утилита printfпродолжает повторно использовать формат, если остались аргументы после того, как они были израсходованы в предыдущих раундах:

Используется, например, как:

$ printf '%*s%c' 3 x1 '|' 4 y1  '|' 3 z1 "$NL" \
                 3 x2 '|' 4 y22 '|' 3 z2 "$NL"
 x1|  y1| z1
 x2| y22| z2

Для форматирования вывода в виде столбцов. Теперь, что ожидается в качестве аргументов ширины, поведение зависит от реализации printf.

  • Для встроенных функций zshи AT&T kshэто может быть любое арифметическое выражение (, как и в большинстве мест, где ожидается число ). Итак, 1+1или 2 означают одно и то же. Aкак арифметическое выражение разрешается в значение $A, или 0 означает, что $Aне установлено или пусто.
  • GNU printfи printf, встроенные в bashи dash, принимают только десятичные, восьмеричные или шестнадцатеричные литеральные константы (, поэтому 020, 16 и 0x10 означают одно и то же )с ведущим (но не конечные )пробелы игнорируются и возвращают сообщение об ошибке (, но в противном случае используйте любой допустимый номер, если он найден в начале аргумента, или 0, если нет ), если он не распознан как допустимый номер.
  • Встроенная функция
  • yashprintfв настоящее время не поддерживает%*s

Так:

printf '%*s%c' A B C

Будет выводить BCв kshи zsh, если $Aне содержит арифметического выражения, которое разрешается в число с целой частью, отличной от 0.

$ A=5.2*2 zsh -c "printf '%*s%c' A B C"
         BC

И вывод BCв bash/ dash/GNU, но также сообщение об ошибке, поскольку Aне является допустимой десятичной/восьмеричной/шестнадцатеричной литеральной константой.

zshили kshмогли выводить сообщения об ошибках, если арифметическое выражение недействительно, и, как и везде, где вычисляется арифметическое выражение, также могли запускать произвольные команды с неправильными переменными в среде:

$ A=1+ zsh -c "printf '%*s%c' A B C"
zsh:1: bad math expression: operand expected at end of string
BC
$ A='psvar[0$(uname>&2)]' zsh -c "printf '%*s%c' A B C"
Linux
BC
1
15.12.2019, 21:02
3 ответа
awk -v file2="input2.txt" -F'/' '{
  while ((getline line < file2) > 0){
    if (line ~ "^"$1) print line FS $2
  }
  close(file2)
}' input1.txt

Это в основном то, что вы описали. Для каждой строки в input1.txtчитаются все строки из input2.txtи сравниваются с началом $1. При совпадении строка input2.txtпечатается с разделителями /и $2.

1
27.01.2020, 23:55

Другое awkрешение, основанное на предоставленных примерах файлов:

$ cat demo.awk
BEGIN { FS="/"; while ((getline < "input2.txt" ) > 0 ) { s[i++] = $0 } }

{ for (i in s)
    if (s[i] ~ "^"$1) { print s[i] FS $2 }
    # alternative tests
    # if (index(s[i], $1)) { print s[i] FS $2 }
    # if (index(s[i], $1) == 1) { print s[i] FS $2 }
}

Выход:

$ awk -f demo.awk input1.txt
example123/world
example234/world
example123/forever
example234/forever
$
-1
27.01.2020, 23:55

Вот как выполнить частичное совпадение строки:

$ cat tst.awk
BEGIN { FS=OFS="/" }
NR==FNR {
    strings[$1]
    next
}
{
    for (string in strings) {
        if ( index(string,$1) ) {
            print string, $2
        }
    }
}

$ awk -f tst.awk input2.txt input1.txt
example234/world
example123/world
example234/forever
example123/forever

Если вы хотите совпадение только в начале строки, просто измените index(...)на index(...) == 1.

0
27.01.2020, 23:55

Теги

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