Почему эта первая запятая в этом массиве printf?

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

Заметная слабость: если вы предоставляете «числовую строку» любого из далее функция будет неправильно возвращать «число»:

  • integer
  • 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.

0
03.11.2016, 17:50
2 ответа

Вы пропустили строку

bar=${bar:1}

из ответа, связанного с ; перед строкой sed необходимо указать

header=${header:1}

, чтобы удалить начальную запятую.

4
28.01.2020, 02:14

Почему бы не использовать встроенные в 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
$ 
3
28.01.2020, 02:14

Теги

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