falsa, la página del manual de corte no explica esto y es, en general, no es informativo
UncleZeiv
2
Además, el "corte de información" no mejora en este caso.
Cardiff Space Man
3
@ mklement0 si recuerdo, estaba respondiendo a un comentario que desde entonces se ha eliminado, que rechazaba esta pregunta como respondida en la página de manual, que en mi opinión era "falsa", independientemente de que haya una buena razón para ello. o no, ahora, aunque reconozco que podría haber una buena razón para esta falta de información, sigo pensando que la documentación sin ejemplos de uso común a menudo es al menos irritante, cuando no es completamente inútil
UncleZeiv
3
@UncleZeiv Lo tengo; gracias por aclararlo; Dado el interés en esta pregunta, es justo asumir que la manpágina no es suficiente. Echemos un vistazo: " -d delimÚselo delimcomo delimitador de campo en lugar del carácter de tabulación". (BSD cut, pero la versión GNU y la especificación POSIX dicen lo mismo). El uso de un shell para invocar cut- el típico caso - por lo tanto requiere que saber cómo generalmente pasan un espacio como argumento usando la sintaxis del shell , lo que sin duda no es el cuttrabajo de página de manual. Sin embargo, los ejemplos del mundo real siempre ayudan, y la página de manual de GNU carece de ellos.
¿Puedes decirle a cut que use cualquier número de cierto carácter como delimitador, como en RegEx? por ejemplo, cualquier número de espacios, por ejemplo \ s +
anfibio
3
@foampile No, no creo que puedas.
Jonathan Hartley
66
No puede usar expresiones regulares con cut, pero puede con el cutsque intenta "arreglar" todas las cutlimitaciones: github.com/arielf/cuts
arielf
¿Puedes obtener cada tercer campo delimitado por espacios? como cut -d ' ' -f 3,6,9,12,15,18sin tener que especificar cada número?
Monocito
169
Por lo general, si usa el espacio como delimitador, desea tratar varios espacios como uno solo, porque analiza la salida de un comando alineando algunas columnas con espacios. (y la búsqueda de Google para eso me llevó aquí)
En este caso, un solo cutcomando no es suficiente y debe usar:
Gracias por el ejemplo de uso de awk, justo lo que necesitaba.
spazm
44
Para complementar las respuestas existentes y útiles; punta del sombrero a QZ Support por alentarme a publicar una respuesta por separado:
Aquí entran en juego dos mecanismos distintos :
(a) si cuten sí requiere el delimitador (espacio, en este caso) se pasa a la -dopción de ser un argumento separado o si es aceptable para añadirlo directamente a -d.
(b) cómo el shell generalmente analiza los argumentos antes de pasarlos al comando que se invoca.
Si la SINOPSIS de una utilidad estándar muestra una opción con un argumento de opción obligatorio, una [...] aplicación conforme utilizará argumentos separados para esa opción y su argumento de opción . Sin embargo , una implementación conforme también permitirá que las aplicaciones especifiquen la opción y el argumento de la opción en la misma cadena de argumento sin caracteres intermedios .
En otras palabras: en este caso, como -del argumento de opción es obligatorio , puede elegir si desea especificar el delimitador como :
(s) CUALQUIERA: un argumento separado
(d) OR: como un valor directamente asociado a-d .
Una vez que haya elegido (s) o (d), lo que importa es el análisis literal de cadena del shell - (b):
Con enfoque (s) , todas las siguientes formas son EQUIVALENTES:
-d ' '
-d " "
-d \<space> # <space> used to represent an actual space for technical reasons
Con el enfoque (d) , todas las siguientes formas son EQUIVALENTES:
-d' '
-d" "
"-d "
'-d '
d\<space>
La equivalencia se explica por el procesamiento literal de cadena del shell :
Todas las soluciones anteriores dan como resultado la misma cadena (en cada grupo) cuando las cutve :
(s) : cutve -d, como su propio argumento, seguido de un argumento separado que contiene un carácter espacial, ¡sin comillas ni \prefijo!
(d) : cutve -dmás un carácter espacial, ¡sin comillas ni \prefijo! - Como parte del mismo argumento.
La razón por la cual los formularios en los respectivos grupos son en última instancia idénticos es doble, en función de cómo el shell analiza los literales de cadena :
El shell permite que el literal se especifique tal cual es a través de un mecanismo llamado cita , que puede tomar varias formas :
cadenas de comillas simples : el contenido dentro '...'se toma literalmente y forma un argumento único
cadenas de doble comillas : el contenido dentro "..."también forma un argumento único , pero está sujeto a interpolación (expande referencias variables como $varsustituciones de comandos ( $(...)o `...`) o expansiones aritméticas ( $(( ... ))).
\-comillas de caracteres individuales : un carácter \precedente a un solo carácter hace que ese carácter se interprete como un literal.
Citando se complementa con eliminación de comillas , lo que significa que una vez que la envoltura ha analizado una línea de comando, que elimina los caracteres cita de los argumentos (que encierran '...'o "..."o \instancias) - por lo tanto, el ser de comandos invoca nunca ve los caracteres de comillas .
La persona que sabe que '\' escapa al siguiente personaje sería muy cuidadoso al notar lo que vino después. Usar '\' para escapar de caracteres espaciales como este es un idioma muy común.
Jonathan Hartley
3
@Jonathan Hartley comúnmente la mayoría de los códigos son ilegibles :) :)
Luca Borrione
1
Desde una perspectiva de Linux / Unix, \ fue mi primer intento y funcionó. Estoy de acuerdo en que es menos obvio en comparación con ' ', pero estoy seguro de que muchos se alegran de leerlo aquí como una garantía de comportamiento. Para una mejor comprensión, consulte el comentario de @ mklement0 a continuación.
tresf
Corrección de @JonathanHartley: "la persona egoísta que sabe que '\' escapa al siguiente personaje y asume que todos los demás también lo saben". Para proyectos personales, esto no se aplica, pero en un entorno de equipo, esa suposición es muy peligrosa (y potencialmente costosa).
Eduard Nicodei
1
@EduardNicodei Oh, estoy de acuerdo. Estábamos hablando de lectores del código ("¿quién se da cuenta ...?"), No de autores. Pero también, en algunos equipos está bien asumir un cierto nivel de competencia. Depende del medio ambiente.
Tenga en cuenta que a partir cut's perspectiva todos los siguientes son idénticos: "-d ", '-d ', -d" ", -d' ', y -d\<space>: todas las formas directamente Incluya el argumento opción (un espacio) a la opción ( -d) y el resultado en la exacta misma cadena en el momento en cutque ve: una sola argumento que contiene d seguido de un espacio, después de que el shell haya realizado la eliminación de comillas
mklement0
1
La respuesta de @ mklement0 debería ser la respuesta. Es el más completo en esta página (aunque es un comentario).
tresf
@ QZSupport: agradezco el sentimiento y el aliento; me ha inspirado a publicar mi propia respuesta con información de fondo adicional.
mklement0
1
Jajaja fascinante descubrimiento!
Harry
4
No puede hacerlo fácilmente con cortar si los datos tienen, por ejemplo, múltiples espacios. He encontrado útil normalizar la entrada para un procesamiento más fácil. Un truco es usar sed para la normalización como se muestra a continuación.
echo -e "foor\t \t bar"| sed 's:\s\+:\t:g'| cut -f2 #bar
scut , una utilidad de corte (más inteligente pero más lenta que hice) que puede usar cualquier perl regex como un token de última hora. Romper en espacios en blanco es el valor predeterminado, pero también puede romper en expresiones regulares de múltiples caracteres, expresiones regulares alternativas, etc.
scut -f='6 2 8 7'< input.file > output.file
entonces el comando anterior rompería las columnas en espacios en blanco y extraería los cols (basados en 0) 6 2 8 7 en ese orden.
Tengo una respuesta (admito una respuesta algo confusa) que involucra sedexpresiones regulares y grupos de captura:
\S* - primera palabra
\s* - delimitador
(\S*) - segunda palabra - capturada
.* - resto de la línea
Como sedexpresión, el grupo de captura necesita escapar, es decir \(y\) .
El \1devuelve una copia del grupo capturado, es decir, la segunda palabra.
$ echo "alpha beta gamma delta"| sed 's/\S*\s*\(\S*\).*/\1/'
beta
Cuando miras esta respuesta, es algo confuso, y, puedes pensar, ¿por qué molestarse? Bueno, espero que algunos digan "¡Ajá!" y usará este patrón para resolver algunos problemas complejos de extracción de texto con una sola sedexpresión.
man
página no es suficiente. Echemos un vistazo: "-d delim
Úselodelim
como delimitador de campo en lugar del carácter de tabulación". (BSDcut
, pero la versión GNU y la especificación POSIX dicen lo mismo). El uso de un shell para invocarcut
- el típico caso - por lo tanto requiere que saber cómo generalmente pasan un espacio como argumento usando la sintaxis del shell , lo que sin duda no es elcut
trabajo de página de manual. Sin embargo, los ejemplos del mundo real siempre ayudan, y la página de manual de GNU carece de ellos.Respuestas:
Donde 2 es el número de campo del campo delimitado por espacios que desea.
fuente
cut
, pero puede con elcuts
que intenta "arreglar" todas lascut
limitaciones: github.com/arielf/cutscut -d ' ' -f 3,6,9,12,15,18
sin tener que especificar cada número?Por lo general, si usa el espacio como delimitador, desea tratar varios espacios como uno solo, porque analiza la salida de un comando alineando algunas columnas con espacios. (y la búsqueda de Google para eso me llevó aquí)
En este caso, un solo
cut
comando no es suficiente y debe usar:O
fuente
Para complementar las respuestas existentes y útiles; punta del sombrero a QZ Support por alentarme a publicar una respuesta por separado:
Aquí entran en juego dos mecanismos distintos :
(a) si
cut
en sí requiere el delimitador (espacio, en este caso) se pasa a la-d
opción de ser un argumento separado o si es aceptable para añadirlo directamente a-d
.(b) cómo el shell generalmente analiza los argumentos antes de pasarlos al comando que se invoca.
(a) se responde con una cita de las directrices POSIX para servicios públicos (énfasis mío)
En otras palabras: en este caso, como
-d
el argumento de opción es obligatorio , puede elegir si desea especificar el delimitador como :-d
.Una vez que haya elegido (s) o (d), lo que importa es el análisis literal de cadena del shell - (b):
Con enfoque (s) , todas las siguientes formas son EQUIVALENTES:
-d ' '
-d " "
-d \<space> # <space> used to represent an actual space for technical reasons
Con el enfoque (d) , todas las siguientes formas son EQUIVALENTES:
-d' '
-d" "
"-d "
'-d '
d\<space>
La equivalencia se explica por el procesamiento literal de cadena del shell :
Todas las soluciones anteriores dan como resultado la misma cadena (en cada grupo) cuando las
cut
ve :(s) :
cut
ve-d
, como su propio argumento, seguido de un argumento separado que contiene un carácter espacial, ¡sin comillas ni\
prefijo!(d) :
cut
ve-d
más un carácter espacial, ¡sin comillas ni\
prefijo! - Como parte del mismo argumento.La razón por la cual los formularios en los respectivos grupos son en última instancia idénticos es doble, en función de cómo el shell analiza los literales de cadena :
'...'
se toma literalmente y forma un argumento único"..."
también forma un argumento único , pero está sujeto a interpolación (expande referencias variables como$var
sustituciones de comandos ($(...)
o`...`
) o expansiones aritméticas ($(( ... ))
).\
-comillas de caracteres individuales : un carácter\
precedente a un solo carácter hace que ese carácter se interprete como un literal.'...'
o"..."
o\
instancias) - por lo tanto, el ser de comandos invoca nunca ve los caracteres de comillas .fuente
También puede decir:
Tenga en cuenta que hay dos espacios después de la barra invertida.
fuente
\
fue mi primer intento y funcionó. Estoy de acuerdo en que es menos obvio en comparación con' '
, pero estoy seguro de que muchos se alegran de leerlo aquí como una garantía de comportamiento. Para una mejor comprensión, consulte el comentario de @ mklement0 a continuación.Me acabo de descubrir que también se puede utilizar
"-d "
:Prueba
fuente
'-d '
.cut
's perspectiva todos los siguientes son idénticos:"-d "
,'-d '
,-d" "
,-d' '
, y-d\<space>
: todas las formas directamente Incluya el argumento opción (un espacio) a la opción (-d
) y el resultado en la exacta misma cadena en el momento encut
que ve: una sola argumento que contiene d seguido de un espacio, después de que el shell haya realizado la eliminación de comillasNo puede hacerlo fácilmente con cortar si los datos tienen, por ejemplo, múltiples espacios. He encontrado útil normalizar la entrada para un procesamiento más fácil. Un truco es usar sed para la normalización como se muestra a continuación.
fuente
scut , una utilidad de corte (más inteligente pero más lenta que hice) que puede usar cualquier perl regex como un token de última hora. Romper en espacios en blanco es el valor predeterminado, pero también puede romper en expresiones regulares de múltiples caracteres, expresiones regulares alternativas, etc.
entonces el comando anterior rompería las columnas en espacios en blanco y extraería los cols (basados en 0) 6 2 8 7 en ese orden.
fuente
Tengo una respuesta (admito una respuesta algo confusa) que involucra
sed
expresiones regulares y grupos de captura:\S*
- primera palabra\s*
- delimitador(\S*)
- segunda palabra - capturada.*
- resto de la líneaComo
sed
expresión, el grupo de captura necesita escapar, es decir\(
y\)
.El
\1
devuelve una copia del grupo capturado, es decir, la segunda palabra.Cuando miras esta respuesta, es algo confuso, y, puedes pensar, ¿por qué molestarse? Bueno, espero que algunos digan "¡Ajá!" y usará este patrón para resolver algunos problemas complejos de extracción de texto con una sola
sed
expresión.fuente