Ускоренная скрипт, определяющий, если все столбцы в строке одинаковы или нет

Вам нужно ввести некоторые команды в командную строку. Прежде всего:

sudo apt-get update  

(это обновит исходные коды программного обеспечения)

, а затем

sudo apt-get upgrade  

(это обновит все до последней версии)

4
16.12.2018, 06:29
4 ответа
$ awk -F, '{ for (i=2; i<=NF; ++i) if ($i != $1) { print "no_match"; next } print $1 }' file
1-69
no_match
1-46
no_match
6-1
5-51
4-59

Извините, но я даже не посмотрел ваш код, слишком много всего происходит. Когда вы обнаружите, что вызываете awkтри раза в теле цикла для одних и тех же данных, вам придется искать другие способы сделать это более эффективно. Кроме того, если вы задействуете awk, вам не нужны grepи cut, так как awkлегко смогут выполнять свои задачи (, которые в данном случае не нужны ).

Приведенный выше сценарий awkсчитывает строку, разделенную запятыми -, и сравнивает каждое поле с первым полем. Если какой-либо из тестов не пройден, печатается строка no_match, и сценарий продолжает работу со следующей строки. Если цикл завершается (без обнаружения несоответствия ), печатается первое поле.

Как сценарий:

#!/usr/bin/awk -f

BEGIN { FS = "," }

{
    for (i=2; i<=NF; ++i)
        if ($i != $1) {
            print "no_match"
            next
        }

    print $1
}
  • FS— это разделитель полей ввода, который также можно установить с помощью параметра -Fв командной строке. awkразделит каждую строку этого символа для создания полей.
  • NF— количество полей в текущей записи («столбцов на строке» ).
  • $iссылается на i :-е поле в текущей записи, где iможет быть переменной или константой (, как в$1).

Связанные:


СУХОЙ вариант:

#!/usr/bin/awk -f

BEGIN { FS = "," }

{
    output = $1

    for (i=2; i<=NF; ++i)
        if ($i != output) {
            output = "no_match"
            break
        }

    print output
}
5
27.01.2020, 20:49

Awk — полноценный язык программирования. Вы уже используете его. Но не используйте его только для простых задач с несколькими вызовами в строке, используйте его для всей задачи. Используйте разделитель полей в awk, не используйте cut. Выполните полную обработку в awk.

awk -F',' '
{ 
  eq=1; 
  for (i = 2; i <= NF; i++)
    if ($1 != $i)
      eq=0;
  print eq ? $1 : "no_match";
}
' $1

1
27.01.2020, 20:49

В Perl List::MoreUtilsпутем вычисления элементов distinct/uniqв скалярном контексте:

perl -MList::MoreUtils=distinct -F, -lne '
  print( (distinct @F) > 1 ? "no_match" : $F[0])
' example 
1-69
no_match
1-46
no_match
6-1
5-51
4-59
1
27.01.2020, 20:49

Вы также можете сделать это с помощью редактора sed, как показано на рисунке:

sed -e '
    s/^\([^,]*\)\(,\1\)*$/\1/;t
    s/.*/NOMATCH/
' input.csv

Здесь мы полагаемся на regex, чтобы умножить себя и достичь конца строки. Если это возможно, завершите ввод первым полем, в противном случае замигайте NOMATCH.

Пояснение:

Вот что творится у меня в голове, когда я вижу этот пбм:
Думайте о comma-separated fieldsкак о stonesразных цветов. И изобразите их, можно ли их расположить в ряд как повторение первого камня, с запятой перед ними.

Что-то вроде:

STONEA,STONEA,STONEA,STONEA... all the way to end of line

Теперь с точки зрения терминологии регулярных выражений это становится:

^ (STONEA) (,\1) (,\1) (,\1)... all the way to end of line

^ (STONEA) (,\1)* $

Выход:

1-69
NOMATCH
1-46
NOMATCH
6-1
5-51
4-59
1
27.01.2020, 20:49

Теги

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