Что делает эта команда grep и sed?

Что делает эта команда grep и sed?

Я уже знаю, что делают некоторые части этой команды:

zgrep -v "org" /path/to/files/* | zgrep "FollowEvent" | zgrep -o 'login":"[^"]*"' | cut -d'"' -f3 | sort | uniq -c | sed '1i{
       s/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/;$a}' > usernames_followevents.txt

Кусок за куском:

1) zgrepиспользуется для grep(поиска) в .json.gzфайлах

2) zgrep -v "org" /path/to/files/*означает поиск записей в каждом файле, /path/to/files/*которые не содержат "org".

3) |— трубка; означает «и затем»

4) zgrep "FollowEvent"означает поиск строки "FollowEvent"среди найденных результатов первого zgrep.

5) |— трубка; означает «и затем»

6) zgrep -o 'login":"[^"]*"'означает поиск непустых совпадений для строки login":"и всего текста после слова «login» в записи.

7) | cut -d'"' -f3означает «а затем взять только третье поле из полученного совпадения», которое в данном случае является именем пользователя.

8) | sort | uniq -cозначает «а затем отсортировать имена пользователей, а затем подсчитать количество уникальных вхождений каждого имени пользователя».

На данный момент мы имеем:

zgrep -v "org" /path/to/files/* | zgrep "FollowEvent" | zgrep -o 'login":"[^"]*"' | cut -d'"' -f3 | sort | uniq -c

который находит во всех записях во всех файлах в /path/to/files/*, которые не содержат строку "org", но содержат строку "FollowEvent", все имена пользователей (которые представляют собой текст в третьем поле после "login"), а затем сортирует эти имена пользователей и подсчитывает количество появлений каждого имени пользователя.

У меня проблема вот с этой частью:

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

Я знаю (или думаю, что знаю) следующее:

1) sed— потоковый редактор, позволяющий манипулировать текстом.

2) sed '1i{означает «в предыдущей строке вставить {»

3) В целом эта команда возвращает {"username":count of that username}все имена пользователей во всех файлах, как обсуждалось ранее. Затем она помещает их в файл с именем usernames_followevents.txt.

4) Часть "\2":означает «заключите имя пользователя, которое является вторым полем (?), в двойные кавычки, а затем вставьте :».

Я хотел бы изменить sedкоманду, но, не понимая остальных деталей, я не могу начать вносить изменения.

Может ли кто-нибудь объяснить, что sedделает каждая часть команды?

решение1

То, как сейчас написана команда sed, неправильно. Это должен быть либо скрипт вроде этого:

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

или в одну строку, например так:

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

Буквально все, что вы помещаете после команд iи aдо новой строки или конца выражения (с -e), напрямую выводится на стандартный вывод.

Давайте разберемся, что он делает:

1i{

1— это адрес строки. Он сообщает sed, когда выполнять команду. Когда содержимое первой строки считывается в пространство шаблона (без завершающего символа новой строки), он iвставляет '{' в стандартный вывод на отдельной строке. Обратите внимание, что пространство шаблона не изменилось, он не добавил '{' в него.

s— команда поиска и замены, самая универсальная команда в sed. \sСоответствует пробелу. \(regex\)Группирует внутри себя регулярное выражение, как в математике, но также сохраняет то, что совпало, в числовом регистре на основе порядка этой группы: от \1 до \9.

Вывод uniq -cпримерно такой:

    occurrences string
    3 user

А теперь сложная часть:

\s*\([0-9]*\)\s*\(.*\)

Все еще на строке 1. Шаблонное пространство — это куча пробелов, затем «3 user». Чтобы сопоставить это, мы ищем пробел ноль или более раз, затем цифру много раз, то есть число (по моему мнению, это должно было быть + вместо *), которое хранится в регистре \1, затем пробел (*, я думаю, не нужен), затем любой символ много раз (опять же, лучше было бы +), который хранится в регистре \2. Так что теперь вхождение находится в \1, а строка/пользователь в \2.

"\2": \1,

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

$a}

$также является адресом строки. Если текущая строка последняя, ​​в данный момент нет, вызовите aкоманду для добавления '}' к стандартному выводу на отдельной строке.

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

Пример вывода:

{
"user": 3,
}

По сути, это формат файла JSON, хотя и с неправильными отступами.

Вот и все. Извините за написание романов :)

Связанный контент