Как распечатать указанные пользователем поля - PullRequest
0 голосов
/ 03 октября 2019

Я пишу сценарий AWK, в котором пользователь будет вводить поля и подсчитывать, сколько раз каждое слово появляется в этом поле. У меня есть код, настроенный так, чтобы он уже распечатывал все поля и сколько раз встречалось каждое слово, но я пытаюсь подсчитать только поля, указанные пользователем. Пользователь будет вводить CSV-файлы, поэтому я устанавливаю FS запятой.

Зная, что AWK предполагает, что все введенные аргументы будут файлом, я устанавливаю аргументы в массив, а затемудалите их из массива ARGV, чтобы он не выдавал ошибку.

#!/usr/bin/awk -f
BEGIN{ FS = ",";
for(i = 1; i < ARGC-1; i++){
    arg[i] = ARGV[i];
    delete ARGV[i];
    }
}


{

for(i=1; i <=NF; i++)
    words[($i)]++

}

END{

for( i in words)
    print i, words[i];

}

Таким образом, если пользователь вводит CSV-файл, такой как ...

A,B,D,D
Z,C,F,G
Z,A,C,D
Z,Z,C,Q

, и пользователь хочет, чтобы для выходных данных учитывалось только поле 3, должно быть ...

C 3
F 1

Или если пользователь 1 и 3 для полей ...

A 2
B 1
C 1
Z 4

Ответы [ 2 ]

2 голосов
/ 03 октября 2019

Другое:

$ awk -F, -v p="1,2" '{   # parameters in comma-separated var
    split(p,f)            # split parameters to fields var
    for(i in f)           # for the given fields
        c[$f[i]]++        # count chars in them
}
END {                     # in the end
    for(i in c)
        print i,c[i]      # output chars and counts
}' file

Вывод для полей 1 и 2:

A 2
B 1
C 1
Z 4
2 голосов
/ 03 октября 2019

Не могли бы вы попробовать следующее (я написал это на мобильном телефоне, поэтому не смог проверить это).

awk -v fields="1,3" '
BEGIN{
 FS=OFS="," 
 num=split(fields,array,",")
 for(j=1;j<=num;j++){
   a[array[j]]
 }
}
{
 for(i=1;i<=NF;i++){
   if(i in a){
     count[$i]++
   }
 }
}
END{
  for(h in count){
     print h,count[h]
  }
}
'   Input_file

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

Объяснение: Следующее предназначено только для пояснения.

-v fields="1,3" создавая переменную с именем fields, значение которой определяется пользователем, она должна быть разделена запятыми, для примера, который я взял 1 и 3, вы можете сохранить его в соответствии с вашими потребностями.

BEGIN{......} здесь начинается раздел BEGIN, где упоминается разделитель полей и разделитель полей вывода в виде запятой для всех строк файла Input_file. Затем, используя split, я разделяю переменные поля на массив с именем array, разделителем которого является запятая. Переменная num имеет переменную длины полей. В главной роли цикл от 1 до до значения num. В нем создается массив с именем a, индекс которого является значением массива, индекс которого является переменной j value.

MAIN Раздел: теперь запускается цикл for, который пересекает все поля строк. Затем он проверяет, поступает ли какой-либо номер поля в массив с именем a, который мы создали в разделе BEGIN; если да, то он создает массив с именем count с индексом текущего столбца +, тоже считая его. Что нам нужно в соответствии с требованием OP.

Наконец, в разделе END этой программы, проходящем через счетчик массивов и печатаем его индексы с их счетами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...