Спецификация формата %*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
не установлено или пусто. printf
и printf
, встроенные в bash
и dash
, принимают только десятичные, восьмеричные или шестнадцатеричные литеральные константы (, поэтому 020, 16 и 0x10 означают одно и то же )с ведущим (но не конечные )пробелы игнорируются и возвращают сообщение об ошибке (, но в противном случае используйте любой допустимый номер, если он найден в начале аргумента, или 0, если нет ), если он не распознан как допустимый номер. yash
printf
в настоящее время не поддерживает%*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
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
.
Другое 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
$
Вот как выполнить частичное совпадение строки:
$ 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
.