Как отформатировать больше переменных в Bash и взять их в тот же файл .txt с ожидаемым порядком? - PullRequest
0 голосов
/ 05 апреля 2019

Я пытаюсь решить одну проблему в Bash.У меня довольно много .txt файлов с регистрационными данными.Я хочу создать новый файл .txt, чтобы ежедневно регистрировать новых зарегистрированных пользователей, а в конце файла в новой строке указывать общее количество пользователей.

Мой сценарий уже работает почти правильно (с точки зрения результата), и я попытался решить его с помощью другой скобки или перенести данные в переменную.

В любом случае, это мой сценарий:

route_from=/route/*
saved=daily_registrations.txt
var1=Total_registrations:

cat $route_from | cut -f1,2 -d' ' | sort -V | uniq -c > /route/$saved #Cuts New users number | file number | date
echo $var1 >> /route/$saved #"Total_registrations:"
cat $route_from | wc -l >> /route/$saved #Total user number

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

New users number | file number | date
New users number | file number | date
New users number | file number | date
Total_registrations: number 

Но теперь мой фактический результат выглядит так:

New users number | file number | date
New users number | file number | date
New users number | file number | date
Total_registrations: 
number 

Ответы [ 3 ]

2 голосов
/ 05 апреля 2019

Каждая из последних двух строк выдает выходные данные, которые направлены в файл, по характеру bash они обе записаны в отдельной строке.Я предлагаю вам объединить их для вывода обоих одновременно, используя подоболочку для вычисления строк:

echo $var1 $(cat $route_from | wc -l) >> /route/$saved

или

echo $var1 `cat $route_from | wc -l` >> /route/$saved

Это должно записать содержимое $var кака также количество строк в вашем файле с использованием одной и той же команды echo.

Кроме того, лучше не cat файл и не передавать его через команду wc, это можно сделать с помощьюредирект как таковой:

wc -l < $route_from

Для файла длиной около 500 строк в моей системе и 1000 запусков это немного быстрее:

[user@host ~]$
 time for i in `seq 1000`; do cat $route_from | wc -l > /dev/null; done

real    0m2.480s
user    0m0.814s
sys     0m1.783s
[user@host ~]$ time for i in `seq 1000`; do wc -l < $route_from > /dev/null; done

real    0m1.971s
user    0m0.537s
sys     0m0.855s
[user@host ~]$

Таким образом, я бы сделал это так:

echo $var1 `wc -l < $route_from` >> /route/$saved
1 голос
/ 06 апреля 2019

Я написал решение POSIX awk.

awk -v OFS=' | ' '
  {
    Regs[$1 OFS $2]++
    total++
  } 
  END {
    for(reg in Regs) print Regs[reg], reg
    print "Total: " total
  }
' /route/* |sort -V >/route/daily_registrations

OFS: Разделитель полей вывода

R[$1 OFS $2]++: Увеличить массив, индекс которого состоит из первых двух столбцов, разделенныхна |.

END{...}: предшествовать каждому индексу с шагом, а затем выводить итоговое значение.

0 голосов
/ 05 апреля 2019

Заменить последние 2 строки на:

echo -e "$var1 \c" >> /route/$saved #"Total_registrations:"
cat $route_from | wc -l >> /route/$saved #Total user number

\c гарантирует, что символ новой строки не добавляется, и оттуда происходит следующее добавление

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