Найти все вхождения строки после другой во всех файлах

Apache работает как непривилегированный пользователь, известный как www-data , в дистрибутивах Debian по весьма уважительной причине: безопасность.

Это считается хорошей практикой безопасности при работе с демонами, отказывающимися от прав привилегий, избегая, насколько это возможно, создания файлов конфигурации или файлов данных с владельцем непривилегированного пользователя, который запускает демон - как таковой, если Пользователь Apache скомпрометирован, злоумышленникам будет гораздо сложнее возиться с вещами или испортить сайт.

По возможности рекомендую создавать сайты с разными пользователями, а права чтения давать только группе www-data; и иметь доступ на запись к www-данным только в каталогах, которые действительно в них нуждаются. Однако даже этого можно избежать с помощью mod-ruid2.

mod-ruid2 позволяет фактически запускать каждый сайт / виртуальный хост вместе с их владельцем, и работать с моделью безопасности страниц намного проще. Это устраняет необходимость создания всемирных каталогов с возможностью записи. Это также гарантирует, что в случае компрометации одного виртуального хоста злоумышленник не сможет внедрить вредоносное ПО в другие виртуальные хосты.

mod-ruid2 также рекомендуется для людей с моделью хостинга, и мы используем его здесь для запуска нескольких сотен сайтов, что весьма успешно.

К сожалению, документации по mod-ruid2 немного, и мне пришлось написать более подробный пост, чтобы описать его здесь, в Unix и Linux .

1
27.03.2019, 21:13
4 ответа

Предполагая, что у вас всегда есть логин и значение в двойных кавычках, следующих друг за другом без пробелов, вот конструкция для grep и подсчета:

grep -o 'login":"[^"]*"' * | cut -d'"' -f3 | sort | uniq -c

Это создаст список входов в систему с количеством вхождений.

Теперь нам нужно сформировать из него нужный вам формат json. sedможет сделать это за вас:

| sed '1i{
       s/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/;$a}'

Здесь sedпоместит {в начало блока и }в его конец и изменит вывод uniqна ожидаемый формат json.

UPD :В итоге итоговая команда должна выглядеть так:

grep -o 'login":"[^"]*"' * | cut -d'"' -f3 | sort | uniq -c | sed '1i{
       s/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/;$a}' > file.txt
2
27.01.2020, 23:18

@rush использование sedне работало в моей оболочке, поэтому я пошел по этому пути

grep -Poh '(?<=login":")[^"]*' json* | sort | uniq -c | awk  -v OFS=': ' 'BEGIN{print "{"}{print $2, $1}END{print"}"}' | sed -E 's/([0-9])$/\1,/g;s/:/\":/g;s/^([^{}])/\"\1/g'

Множественное число sedможно изменить, если ваша оболочка позволяет экранировать "и печатать их в операторе awk.

grep -Poh '(?<=login":")[^"]*' json* | sort | uniq -c | awk  -v OFS=': ' 'BEGIN{print "{"}{print \"$2\", $1}END{print"}"}' | sed -E 's/([0-9])$/\1,/g'

У меня в оболочке awkподавился \"во втором скрипте. Не уверен, почему, но уверен, что кто-то там скажет мне.

Я также пробовал jq, но он задыхался от файлов json. Синтаксическая ошибка

.
"this":"is' #is written so I edited these to
"this":"is"

Также jqне понравилась конструкция

{"a":"strange"} # so I also edited these to
b: {"a":"strange"}

Если исходные файлы должны соответствовать внесенным изменениям, тогда jqработает

jq '.login' json* | sort | uniq -c | awk -v OFS=': ' 'BEGIN{print "{"}{print $2, $1}END{print"}"}' | sed -E 's/([0-9])$/\1,/g'
0
27.01.2020, 23:18

Чтобы получить все имена пользователей, т. е. всю строку, связанную с ключом login, из правильно сформированного документа JSON , не зная структуры документа:

jq -r '..|select(.login?).login' file.json

Применение этого к нескольким файлам JSON, а также сортировка и подсчет результата:

jq -r '..|select(.login?).login' *.json | sort | uniq -c

Здесь используется выражение jq

  • ..:Повторный просмотр всех ключей и значений.
  • select(.login?):Выберите обнаруженные объекты, содержащие ключ login.
  • .login:Получите значение для этого ключа.

Словарь, который вы хотели бы иметь, основанный на приведенном выше jqвыражении:

jq -sr '[..|select(.login?).login]|group_by(.)|map({key:.[0],value:length})|from_entries' *.json

Тестирование:

$ cat file.json
{"this":"is", "A":{"login":"username2"}, "type":{"of":"object", "but":"please"},
 "go":"withit", "login":"me"}
$ jq -sr '[..|select(.login?).login]|group_by(.)|map({key:.[0],value:length})|from_entries' file.json
{
  "me": 1,
  "username2": 1
}

Дважды передать один и тот же файл:

$ jq -sr '[..|select(.login?).login]|group_by(.)|map({key:.[0],value:length})|from_entries' file.json f
ile.json
{
  "me": 2,
  "username2": 2
}

Используйте jqс -cдля получения однострочного компактного вывода.

Для нашего примера файла jq -sr '[..|select(.login?).login]' file.jsonдаст

[
  "me",
  "username2"
]

Прохождение через group_by(.)дает

[
  [
    "me"
  ],
  [
    "username2"
  ]
]

Часть map({key:.[0],value:length})дает

[
  {
    "key": "me",
    "value": 1
  },
  {
    "key": "username2",
    "value": 1
  }
]

и from_entriesв конце дают окончательный результат.

1
27.01.2020, 23:18

Как насчет использования perl-хэша с ключом для совпадения с регулярным выражением, который вы можете преобразовать с помощью модуля JSON:

$ perl -MJSON -lne '$h{$1}++ for /(?<="login":")(.*?)(?=")/g }{ print encode_json \%h' file1 file2
{"username3":1,"username2":1,"username1":2}
1
27.01.2020, 23:18

Теги

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