проблема с AWK при подсчете количества записей

foreach mod ("`lsmod`")
   set ml = ($mod)
   echo "$ml[1]"
end
0
19.05.2021, 17:37
2 ответа

Вы делаете echo "$error_count"или что-то подобное после запуска кода, но у вас нет такой переменной, и вместо этого вы фактически намеревались сделать echo "$err_count".

1
28.07.2021, 11:31

Как отмечено steeldriver, ширина c никогда не будет больше, чем ваш предел:

c = substr($0, 1, 5)

Длина cникогда не будет > 5.

Кроме того, это пусто / пусто, потому что в сценарии awk есть синтаксическая ошибка. Это должно быть напечатано в оболочке, если вы не сделаете что-то вроде2>/dev/null

Это больше не применяется после последнего обновления. Но из того, что я вижу, это не было исправлено вами. Просто для ясности:

    if( (length(c) >  p  && NR > 1 )
#       ^
#       +--- Never closed.

Помимо этого ваша редакция также поносит больше. Вам не нужно \для продолжения скрипта на следующей строке. То есть:

  • Не { \, а{

  • Нет

    ... "/dev/stderr"\
        ++count
    
  • Но

      ... "/dev/stderr"
    ++count
    

Использование точек с запятой в конце инструкций допустимо, но для того, чтобы код был более читабельным, не смешивайте их. Либо используйте ;в конце всех операторов, либо ничего, если, конечно, у вас по какой-то причине нет более одного оператора в строке. Так:

Нет:

    printf "%s: %d", $1, $2;
    ++foo
    ++bar;
    printf "%s: %d", $3, $4

Но:

    printf "%s: %d", $1, $2
    ++foo
    ++bar
    printf "%s: %d", $3, $4

Или (мало используется из того, что я видел):

    printf "%s: %d", $1, $2;
    ++foo;
    ++bar;
    printf "%s: %d", $3, $4;

Это также концепция использования substr()из $0и обрезки на sub().

Разделителем awk по умолчанию является <пробел>. Это обрабатывается иначе, чем другие разделители символов. То есть :несколько пробелов объединяются в один разделитель. Таким образом, обе строки в:

A B C
  A    B     C

Результат в:

$1 == A
$2 == B
$3 == C

Что касается проблемы, вы могли бы сделать что-то вроде этого:

awk \
    -v width_max=5 \
    -v field_validate=1 \
'
BEGIN {
    err_count = 0
}
$1 == "header" {
    next
}
NF < field_validate || length($field_validate) > width_max {
    printf "%s:%d:%d:%s\n", FILENAME, NF, FNR, $0 > "/dev/stderr"
    ++err_count
}
END {
    printf "%d", err_count
}

' sample

Обратите внимание, что вы, возможно, поместите чек NFкак отдельный чек. Что-то вроде:

NF != field_count {
    # NF does not match with required fields
}

Где field_count— определенная переменная.

Простой пример скрипта, на который вы можете посмотреть в отношении FS, NF и т. д.

awk -v field_count=3 \
'
NF != field_count {
    printf "NF mismatch %d != %d\n", NF, field_count
}
{
    printf "<%s><%s><%s>\n", $1, $2, $3
}
' <<EOF
AA BB CC
AA      BB    CC
   AA   BB      CC
AA BB
AA BB CC DD
EOF
1
28.07.2021, 11:31

Теги

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