Ya sé qué hacen los fragmentos de este comando:
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
Pieza por pieza:
1) zgrep
se utiliza para grep
(buscar) .json.gz
archivos
2) zgrep -v "org" /path/to/files/*
significa buscar entradas en cada archivo que /path/to/files/*
no contengan "org"
.
3) |
es una tubería; significa "y luego"
4) zgrep "FollowEvent"
significa buscar la cadena "FollowEvent"
dentro de los resultados encontrados del primer zgrep.
5) |
es una tubería; significa "y luego"
6) zgrep -o 'login":"[^"]*"'
significa buscar coincidencias no vacías para la cadena login":"
y todo el texto que sigue a la palabra "iniciar sesión" en la entrada.
7) | cut -d'"' -f3
significa "y luego tomar sólo el tercer campo de la coincidencia resultante", que es, en este caso, un nombre de usuario.
8) | sort | uniq -c
significa "y luego ordenar los nombres de usuario y luego contar el número de instancias únicas de cada nombre de usuario".
Hasta ahora tenemos:
zgrep -v "org" /path/to/files/* | zgrep "FollowEvent" | zgrep -o 'login":"[^"]*"' | cut -d'"' -f3 | sort | uniq -c
lo cual es encontrar, en todas las entradas de todos los archivos en /ruta/a/archivos/* que no contienen la cadena "org", pero sí la cadena "FollowEvent", todos los nombres de usuario (que es el texto en el tercer campo después de " iniciar sesión"), y luego ordenar estos nombres de usuario y contar el número de veces que aparece cada nombre de usuario.
Mi problema es con esta parte:
sed '1i{ s/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/;$a}'
Sé (o creo saber) esto:
1) sed
es un editor de secuencias que permite la manipulación de texto.
2) sed '1i{
significa "en la línea anterior, inserte {"
3) En conjunto, este comando regresa {"username":count of that username}
para todos los nombres de usuario en todos los archivos como se discutió anteriormente. Luego los coloca en un archivo llamado usernames_followevents.txt
.
4) La parte "\2":
significa "poner comillas dobles alrededor del nombre de usuario, que es el segundo campo (?) y luego insertar un :".
Me gustaría manipular el sed
comando, pero sin entender el resto de detalles no puedo empezar a realizar modificaciones.
sed
¿Alguien podría explicar qué hace cada parte del comando?
Respuesta1
La forma en que está escrito el comando sed ahora es incorrecta. Debería ser un script como este:
1i{
s/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/
$a}
o en una sola línea como esta:
sed -e '1i{' -e 's/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/' -e '$a}'
Literalmente, todo lo que pones después de los comandos i
y a
hasta una nueva línea o el final de una expresión (con -e) se imprime directamente en la salida estándar.
En cuanto a lo que hace, analicémoslo:
1i{
1
es una dirección de línea. Le dice a sed cuándo ejecutar un comando. Cuando el contenido de la primera línea se lee en el espacio del patrón (sin la nueva línea final), se i
inserta '{' en la salida estándar en una línea separada. Tenga en cuenta que el espacio del patrón no se modifica, no le agregó el '{'.
s
es el comando de búsqueda y reemplazo, el comando más versátil de sed. \s
coincide con un espacio en blanco. \(regex\)
está agrupando la expresión regular dentro como en matemáticas, pero también almacena lo que coincidió en un registro numérico según el orden de ese grupo: \1 a \9.
La salida de uniq -c
es algo como esto:
occurrences string
3 user
Ahora la parte complicada:
\s*\([0-9]*\)\s*\(.*\)
Todavía en la línea 1. El espacio del patrón es un montón de espacios, luego '3 usuarios'. Para hacer coincidir esto buscamos espacios en blanco cero o más veces, luego un dígito muchas veces, es decir un número (en mi opinión debería haber sido + en lugar de *) que se almacena en el registro \1, luego el espacio (* es Creo que no es necesario), entonces cualquier carácter muchas veces (nuevamente + hubiera sido mejor) que se almacene en el registro \2. Entonces ahora, la ocurrencia está en \1 y la cadena/usuario en \2.
"\2": \1,
Se hizo coincidir toda la línea y se almacenaron las piezas, ahora reemplazamos lo que coincidió con comillas, luego usuario, luego comillas, dos puntos, espacio, ocurrencia y coma.
$a}
$
También es una dirección de línea. Si la línea actual es la última, en este momento no, llame al a
comando para agregar '}' a la salida estándar en una línea separada.
Este es el final del procesamiento del código para esta línea, la impresión automática del espacio del patrón tal como está después de realizar la manipulación, luego se lee el contenido de la segunda línea y se repite todo el ciclo.
Salida de ejemplo:
{
"user": 3,
}
Básicamente es un formato de archivo JSON, aunque con una sangría incorrecta.
Eso es todo. Perdón por escribir novelas :)