У меня есть файлы журнала, подобные этому (это только пробел между ними, но для удобства чтения я изменил это):
Customer Car Bought
François Nissan Pajero 28/05/2016
Matthew Mercedes S 10/01/2019
Andrew Peugeot 508 05/0/2000
Matthew Toyota Hilux 02/10/2012
Мне нужно сделать awk-скрипт, который покажет каждому покупателю, какую машину он купил, вот так:
Matthew, car bought: Mercedes S,Toyota Hilux, number of cars: 2
Francois, car bought: Nissan Pjero, number of cars: 1
Я не могу знать, как это сделать.
Я думаю, я должен создать массив для клиента и один для автомобиля и проиндексировать его номером строки
awk ' { Customer[NR]=$1; Car[NR]=$2} END {}'
Что добавить в КОНЕЦ, я немного в недоумении
Я думал сделать это также:
awk ' { Customer[$1]=$2} END { for (i in Customer) print i,Customer[i]}'
Проблема с этим массивом в том, что он уничтожит предыдущее значение автомобиля в проиндексированном массиве Customer.
(Кроме того, кому-то, кто отвечает на этот вопрос, потребуется более подробная спецификация формата файла. Дополнены ли столбцы табуляцией или пробелами? Если это пробелы, гарантируется ли ширина заполнения постоянной или они могут меняться? Если ширина столбцов может меняться, есть ли любые гарантии использования могу, например, знание того, что между соседними столбцами всегда будет как минимум два пробела и никогда не будет более одного в столбце данных в пределах?)
Привет, столбцы заполнены пробелом, всегда
Это один из четырех вопросов, остальные три относятся к конкретным случаям. если заполнение использует пробелы.
(но спасибо за редактирование; я думаю, что теперь на этот вопрос можно ответить, по крайней мере, если кто-то готов сделать предположения о вкладе, который эти вопросы привнесут в уверенность, и отозвал свое близкое голосование).
Вы согласны с не-awk ответами?
Это, безусловно, интересная дата 05/0/2000
...
Если вас не беспокоит порядок вывода (который не должен совпадать с первым полем Input_file), не могли бы вы попробовать следующее.
awk '
FNR>1{
match($0,/ +.* +/)
var=substr($0,RSTART,RLENGTH)
gsub(/^[[:space:]]+|[[:space:]]+$/,"",var)
a[$1]=(a[$1]?a[$1] OFS:"")var
b[$1]++
}
END{
for(i in a){
print i","a[i]",number of cars: "b[i]
}
}
' Input_file
Обновлено: Добавление решения, которое обеспечит вывод в том же порядке, что и 1-е поле Input_file.
awk '
FNR>1{
if (!b[$1]++){
c[++count]=$1
}
match($0,/ +.* +/)
var=substr($0,RSTART,RLENGTH)
gsub(/^[[:space:]]+|[[:space:]]+$/,"",var)
a[$1]=(a[$1]?a[$1] OFS:"")var
d[$1]++
}
END{
for(i=1;i<=count;i++){
print c[i]","a[c[i]]",number of cars: "d[c[i]]
}
}
' Input_file
Предполагая, что у каждого клиента действительно есть имя из 1 слова, как показано в вашем примере и подразумевается вашим кодом (если нет, то мы будем использовать синтаксический анализ поля с фиксированной шириной для идентификации полей - см. https://stackoverflow.com/a/31947741/1745001):
$ cat tst.awk
NR>1 {
gsub(/^[[:space:]]+|[[:space:]]+$/,"")
cust = $1
gsub(/^[^[:space:]]+[[:space:]]+|[[:space:]]+[^[:space:]]+$/,"")
cars[cust,++numCars[cust]] = $0
custs[cust]
}
END {
for (cust in custs) {
printf "%s, car bought: ", cust
for (carNr=1; carNr<=numCars[cust]; carNr++) {
printf "%s,", cars[cust,carNr]
}
printf " number of cars: %d\n", numCars[cust]
}
}
$ awk -f tst.awk file
Andrew, car bought: Peugeot 508, number of cars: 1
Matthew, car bought: Mercedes S,Toyota Hilux, number of cars: 2
François, car bought: Nissan Pajero, number of cars: 1
С учетом вышеизложенного, если данный клиент покупает автомобиль одного и того же типа (например, Peugeot 508) в несколько дат, все они будут перечислены/подсчитаны в выходных данных.
Для этих данных я бы использовал Splunk
. Он может анализировать до 500 МБ каждый день бесплатно. Вы можете получить любые отчеты и графики, которые вам нравятся.
Мы не являемся службой, которая пишет вашу программу для вас, имея только спецификацию. Покажите конкретную техническую проблему, с которой вы столкнулись, пытаясь решить ее самостоятельно, или, по крайней мере, достаточно ваших собственных усилий, чтобы мы знали, какой уровень понимания вы имеете в настоящее время, чтобы мы знали, сколько объяснений дать.