Tengo un archivo que contiene líneas como
proto=tcp/http sent=144 rcvd=52 spkt=3
proto=tcp/https sent=145 rcvd=52 spkt=3
proto=udp/dns sent=144 rcvd=52 spkt=3
Necesito extraer el valor de proto que es tcp/http, tcp/https, udp/dns.
Hasta ahora he intentado esto grep -o 'proto=[^/]*/'pero solo he podido extraer el valor como proto=tcp/.

sed,awkoperlnogrep.Respuestas:
Asumiendo que esto está relacionado con su pregunta anterior , está yendo por el camino equivocado. En lugar de tratar de juntar fragmentos de guiones que hagan lo que quieras la mayor parte del tiempo y necesiten obtener un guión completamente diferente cada vez que necesites hacer algo lo más mínimo posible, solo crea 1 guión que pueda analizar tu ingrese el archivo en una matriz (a
f[]continuación) que asigna sus nombres de campo (etiquetas) a sus valores y luego puede hacer lo que quiera con el resultado, por ejemplo, dado este archivo de entrada de su pregunta anterior:podemos escribir un script awk que cree una matriz de los valores indexados por sus nombres / etiquetas:
y dado que puede hacer lo que quiera con sus datos simplemente haciendo referencia a ellos por los nombres de campo, por ejemplo, usando GNU awk
-epara facilitar la mezcla de un script en un archivo con un script de línea de comandos:fuente
perlpuede ser más fácil de usar.awky lossedscripts generalmente son más simplesperlporque es esencialmente un superconjunto de ellos, con características adicionales para tareas comunes.s/old/new/gy que sed no sea awk, así que dejemos eso de lado. No estoy de acuerdo con que los scripts de awk complejos sean más simples en perl. Pueden ser más breves, por supuesto, pero la brevedad no es un atributo deseable del software, la concisión lo es, y es extremadamente raro que tengan algún beneficio real, además de que generalmente son mucho más difíciles de leer, por eso la gente publica cosas como zoitz.com / archivos / 13 sobre perl y se refieren a él como un lenguaje de solo escritura, a diferencia de awk. Sin embargo, todavía me gustaría ver un perl equivalente a estoCon
grep -o, tendrá que coincidir exactamente con lo que desea extraer. Como no desea extraer laproto=cadena, no debe coincidir con ella.Una expresión regular extendida que coincidiría con
tcpoudpseguida de una barra y alguna cadena alfanumérica no vacía esAplicando esto en sus datos:
Para asegurarnos de que solo hacemos esto en las líneas que comienzan con la cadena
proto=:Con
sed, eliminar todo antes del primer=y después del primer carácter en blanco:Para asegurarse de que solo hacemos esto en las líneas que comienzan con la cadena
proto=, puede insertar el mismo paso de preprocesamiento con elgrepanterior, o puede usarAquí, suprimimos la salida predeterminada con la
-nopción, y luego activamos las sustituciones y una impresión explícita de la línea solo si la línea coincide^proto=.Con
awk, usando el separador de campo predeterminado, y luego dividiendo el primer campo=e imprimiendo el segundo bit:Para asegurarse de que solo hacemos esto en las líneas que comienzan con la cadena
proto=, puede insertar el mismo paso de preprocesamiento con elgrepanterior, o puede usarfuente
Si está en GNU grep (para la
-Popción), puede usar:Aquí hacemos coincidir la
proto=cadena, para asegurarnos de que estamos extrayendo la columna correcta, pero luego la descartamos de la salida con el\Kbandera.Lo anterior supone que las columnas están separadas por espacios. Si las pestañas también son un separador válido, lo usaría
\Spara hacer coincidir los caracteres que no son espacios en blanco, por lo que el comando sería:Si también desea protegerse contra los campos de coincidencia donde
proto=hay una subcadena, como athisisnotaproto=tcp/https, puede agregar un límite de palabra de la siguiente\bmanera:fuente
grep -oP 'proto=\K\S+'. Elproto=tcp/httppuede ir seguida de una pestaña en lugar de espacios, y la\Sdiferencia[^ ]coincidirá con cualquier carácter que no sea espacio.-oes un GNUismo.-Psolo es compatible con GNUgrepsi está construido con soporte PCRE (opcional en tiempo de compilación).Utilizando
awk:$1 ~ "proto"se asegurará de que solo tomemos medidas en líneas conprotode la primera columnasub(/proto=/, "")removeráproto=de la entradaprint $1imprime la columna restantefuente
Código de golf en las
grepsolucioneso incluso
fuente
Usando el
cutcomando:fuente
httpydns.Solo otra
grepsolución:Y uno similar con
sedimprimir solo el grupo capturado coincidente:fuente
Otro
awkenfoque:Eso establecerá el separador de campo de awk en uno
=o en un espacio. Luego, si la línea coincide con a=, entoncesudotcseguido de unp, imprima el segundo campo.Otro
sedenfoque (no portátil para todas las versiones desed, pero funciona con GNUsed):El
-nmedio "no imprime" y-Epermite expresiones regulares extendidas que nos dan\Spara "no espacios en blanco",+para "uno o más" y los paréntesis para capturar. Finalmente, el/pal final hará que sed imprima una línea solo si la operación fue exitosa, por lo que si hubo una coincidencia para el operador de sustitución.Y, uno perl:
El
-nmedio "lee el archivo de entrada línea por línea y aplica la secuencia de comandos dada por-ea cada línea". El-lañade una nueva línea para cadaprintllamada (y elimina los saltos de línea que salen de la entrada). El script mismo imprimirá el tramo más largo de caracteres que no sean espacios en blanco encontrados después de aproto=.fuente
-Ese está volviendo cada vez más portátil, pero\Sno lo es.[^[:space:]]Es un equivalente más portátil.Aquí hay otra solución bastante fácil:
fuente
grepno coincide con nada.[tc,ud]\*\\/.*busca una aparición det, oc, o,ouod, seguido de un*carácter literal , luegopay una barra invertida. Probablemente quisiste decirgrep -Eo '(tc|ud)p/.* ' file | awk '{print $1}'. Pero entonces, si estás usando awk, es posible que también lo haga la cosa entera en awk:awk -F'[= ]' '/(tc|ud)p/{print $2}' file.[tc,ud]psignifica "uno det,c,,,uodseguidas por unap. Por lo tanto, los partidos aquí sólo porquetcptienecpyudptienedp. Pero también se correspondería,potpetc. También, ahora que tiene el*, que coincidiránppptambién (el*medios "0 o más", por lo que coincidirá incluso cuando no coincide) usted no quiere una clase de caracteres (.[ ]), lo que quiere es un grupo:(tc|ud)(uso con la-Ebandera degrep.) Además, la.*hace coincidir con toda la línea.\*para que el primero*en su comando apareciera como un * y no como una marca de cursiva. Cuando pones el comando en formato de código, hiciste que apareciera el\antes*(lo que provocó que el comando fallara). Cuando edite las publicaciones de otras personas, tenga cuidado de cambiar la apariencia de la publicación de esta manera.ppp. Por supuesto que tienes razón que coincidirá,potp- ouucp,ttp,cutp,ductpod,up.fuente
opciones de corte:
-f- campo-d- delimitadorfuente