Awk имеет 4 типа: "число", "строка", "числовая строка" и "неопределенное".Здесь является функцией для обнаружения того, что:
function o_class(obj, q, x, z) {
q = CONVFMT
CONVFMT = "% g"
split(" " obj "\1" obj, x, "\1")
x[1] = obj == x[1]
x[2] = obj == x[2]
x[3] = obj == 0
x[4] = obj "" == +obj
CONVFMT = q
z["0001"] = z["1101"] = z["1111"] = "number"
z["0100"] = z["0101"] = z["0111"] = "string"
z["1100"] = z["1110"] = "strnum"
z["0110"] = "undefined"
return z[x[1] x[2] x[3] x[4]]
}
Для третьего аргумента split
вам нужно что-то, что не является пробелом, и
не является частью obj
, иначе он будет рассматриваться как разделитель. Я выбрал \1
основано на предложении Стефана. Функция выполняет внутреннюю CONVFMT
переключение, поэтому он должен возвращать правильный результат независимо от значения CONVFMT
во время вызова функции:
split("12345.6", q); print 1, o_class(q[1])
CONVFMT = "%.5g"; split("12345.6", q); print 2, o_class(q[1])
split("nan", q); print 3, o_class(q[1])
CONVFMT = "%.6G"; split("nan", q); print 4, o_class(q[1])
Результат:
1 strnum
2 strnum
3 strnum
4 strnum
Полный набор тестов:
print 1, o_class(0)
print 2, o_class(1)
print 3, o_class(123456.7)
print 4, o_class(1234567.8)
print 5, o_class(+"inf")
print 6, o_class(+"nan")
print 7, o_class("")
print 8, o_class("0")
print 9, o_class("1")
print 10, o_class("inf")
print 11, o_class("nan")
split("00", q); print 12, o_class(q[1])
split("01", q); print 13, o_class(q[1])
split("nan", q); print 14, o_class(q[1])
split("12345.6", q); print 15, o_class(q[1])
print 16, o_class()
Результат:
1 number
2 number
3 number
4 number
5 number
6 number
7 string
8 string
9 string
10 string
11 string
12 strnum
13 strnum
14 strnum
15 strnum
16 undefined
Заметная слабость: если вы предоставляете «числовую строку» любого из далее функция будет неправильно возвращать «число»:
inf
-inf
Для целых чисел это объясняется:
Числовое значение, точно равное значению целого числа должен быть преобразуется в строку эквивалентом вызова функции
sprintf
со строкой%d
в качестве аргументаfmt
Однако inf
и -inf
ведут себя так же; то есть ни один из
на приведенное выше может повлиять переменная CONVFMT
:
CONVFMT = "% g"
print "" .1
print "" (+"nan")
print "" 1
print "" (+"inf")
print "" (+"-inf")
Результат:
0.1
nan
1
inf
-inf
На практике это не имеет особого значения, см. Duck test.
Вы пропустили строку
bar=${bar:1}
из ответа, связанного с ; перед строкой sed
необходимо указать
header=${header:1}
, чтобы удалить начальную запятую.
Почему бы не использовать встроенные в bash подстановки вместо printf
? Из раздела Массивы :
subscripts differ only when the word appears within double quotes. If
the word is double-quoted, ${name[*]} expands to a single word with the
value of each array member separated by the first character of the IFS
special variable, and ${name[@]} expands each element of name to a sep‐
arate word. When there are no array members, ${name[@]} expands to
Итак, вы можете:
$ IFS=,; echo "${ids[*]}"
1,10
$
Также вы можете использовать sed
, чтобы вставить целую строку, например:
$ echo masi > foo
$ IFS=, sed -i "1i${ids[*]}" foo
$ cat foo
1,10
masi
$