Awk программа для сравнения количества полей по пробелам каждой строки - PullRequest
0 голосов
/ 24 февраля 2019

Я пытаюсь проверить, имеет ли каждая строка одинаковую длину (или количество полей) в файле.Я делаю следующее, но, похоже, это не работает.

NR==1 {length=NF}

NR>1 && NF!=length {print}

Может ли это быть выполнено однострочным awk?или программа в порядке.

Пример ввода будет:

12 34 54 56
12 89 34 33
12
29 56 42 42

Мой ожидаемый результат будет "да" или "нет", если они имеют одинаковое количество полей или нет.

Ответы [ 5 ]

0 голосов
/ 24 февраля 2019

это должно сделать

$ awk 'NR==1{p=NF} p!=NF{s=1; exit} END{print s?"No":"Yes"}' file

однако, установка статуса выхода будет лучше, если это будет частью рабочего процесса.

Поскольку эквивалентность имеет переходное свойство, нет необходимостиоставить NF кроме первой строки;установка 0 в качестве значения успеха не требует инициализации до значения по умолчанию.

0 голосов
/ 24 февраля 2019

Эффективная e ven f ields функция оболочки, используя sed для построения регулярного выражения (на основе первой строки ввода) для подачи в GNU grep, который ищет несоответствия длины поля:

# Usage: ef filename
ef() { sed '1s/[^ ]*/[^ ]*/g;q' "$1" | grep -v -m 1 -q -f - "$1" \
       && echo no || echo yes ; }

Для файлов с неровными полями grep -m 1 завершается после первой неоднородной строки - поэтому, если файл имеет длину в миллион строк, но в строке # 2 происходит несоответствие, grep необходимо прочитать только две строки,не миллион.С другой стороны, если нет несоответствия, grep должен будет прочитать миллион строк.

0 голосов
/ 24 февраля 2019

Попробуйте:

awk 'BEGIN{a="yes"} last!="" && NF!=last{a="no"; exit} {last=NF}  END{print a}' file

Как это работает

  • BEGIN{a="yes"}

    Инициализирует переменную a в yes.(Мы предполагаем, что все строки имеют одинаковые числовые поля, пока не доказано обратное.)

  • last!="" && NF!=last{a="no"; exit}

    Если last было присвоено значение и количество полей в текущей строке не совпадает с последним, затем установите a на no и выйдите.

  • {last=NF}

    Обновите last до числа полей в текущей строке.

  • END{print a}

    Перед выходом выведите a.

Примеры

$ cat file1
2 34 54 56
12 89 34 33
12
29 56 42 42
$ awk 'BEGIN{a="yes"} last!="" && NF!=last{a="no"; exit} {last=NF}  END{print a}' file1
no
$ cat file2
2 34 54 56
12 89 34 33
29 56 42 42
$ awk 'BEGIN{a="yes"} last!="" && NF!=last{a="no"; exit} {last=NF}  END{print a}' file2
yes
0 голосов
/ 24 февраля 2019

Вы можете попробовать эту команду, которая проверяет количество полей в каждой строке и сравнивает его с количеством полей в первой строке:

awk 'NR==1{a=NF; b=0} (NR>1 && NF!=a){print "No"; b=1; exit 1}END{if (b==0) print "Yes"}' test.txt

Проверка отменяется в первой строке, число полей которойотличается от первой строки ввода.

Для ввода

12 43 43
12 32

вы получите «Нет»

0 голосов
/ 24 февраля 2019

Я предполагаю, что вы хотите проверить поля всех строк, если они равны или нет, если это так, попробуйте следующее.

awk '
FNR==1{
  value=NF
  count++
  next
}
{
  count=NF==value?++count:count
}
END{
  if(count==FNR){
     print "All lines are of same fields"
}
  else{
     print "All lines are NOT of same fields."
  }
}
'  Input_file

Дополнительные вещи (только еслиrequire): Если вы хотите напечатать содержимое файла, все строки которого имеют одинаковые поля вместе с сообщением yes или all are same fields in file в выводе, попробуйте выполнить следующее.

awk '
{
  val=val?val ORS $0:$0
}
FNR==1{
  value=NF
  count++
  next
}
{
  count=NF==value?++count:count
}
END{
  if(count==FNR){
    print "All lines are of same fields" ORS val
  }
  else{
    print "All lines are NOT of same fields."
  }
}
'   Input_file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...