¿Cómo hacer coincidir los espacios en blanco en sed?

218

¿Cómo puedo hacer coincidir los espacios en blanco en sed? En mis datos, quiero hacer coincidir todos los 3+ caracteres de espacio en blanco posteriores (espacio de tabulación) y reemplazarlos por 2 espacios. ¿Cómo se puede hacer esto?

Peter Smit
fuente

Respuestas:

226

La clase de caracteres \scoincidirá con los caracteres de espacio en blanco <tab>y <space>.

Por ejemplo:

$ sed -e "s/\s\{3,\}/  /g" inputFile

sustituirá cada secuencia de al menos 3 espacios en blanco con dos espacios.


OBSERVACIÓN : Para el cumplimiento de POSIX, use la clase de caracteres en [[:space:]]lugar de \s, ya que esta última es una extensión de sed de GNU. Consulte las especificaciones POSIX para sed y BRE

mrucci
fuente
55
aha! Fue el interruptor que faltaba el que me atrapó.
sequoia mcdowell
25
También tuve que agregar el interruptor '-r' que permite que las expresiones regulares extendidas hagan que sed reconozca '\ s' como espacio.
HUB
39
Con Apple sedtuve que usar [[:space:]]porque \sno funcionó para mí. ¿Quizás \ses una extensión sed de GNU ?
Jared Beck
2
@JaredBeck, gracias, se me estaban acabando las ideas de por qué mi expresión regular simple no funcionaba ... Esto es lamentable, pensé que era una expresión regular extendida estándar ... También -r no funciona y -E se puso en cuclillas
Karthik T
3
En lugar de [[:space:]uno, se podría usar el [[:blank:]]que solo coincida con pestañas horizontales y espacios (pero sin líneas nuevas, pestañas verticales, etc.).
stefanct
67

Esto funciona en MacOS 10.8:

sed -E "s/[[:space:]]+/ /g"
algunas ideas
fuente
2
¿Sabes si esto funciona en todas las distribuciones de Linux?
anfibio
2
Generalmente no, GNU sed no tendrá -E. Desde la página de manual de BSD sed: "Las opciones -E, -a y -i son extensiones de FreeBSD no estándar y pueden no estar disponibles en otros sistemas operativos".
Brad Koch
1
¿Por qué necesita la bandera -E para el operador +? La mayoría de las expresiones probablemente estarían bien con *, entonces esto funcionaría en otras plataformas.
Samuel
55
@Samuel Si usa *, la expresión regular coincidirá con cero o más espacios, y obtendrá un espacio entre cada carácter y un espacio en cada extremo de cada línea. Si no tiene la bandera -E, entonces quiere sed "s/[[:space:]]\+/ /g"hacer coincidir uno o más espacios.
jbo5112
1
FWIW, el sed de NetBSD también admite la -Ebandera.
mcandre
13

Es posible que algunas versiones anteriores de sed no reconozcan \ s como un token de coincidencia de espacios en blanco. En ese caso, puede hacer coincidir una secuencia de uno o más espacios y pestañas con '[XZ] [XZ] *' donde X es un espacio y Z es una pestaña.

Marnix A. van Ammers
fuente
1
Entonces, para la necesidad particular aquí, con un sed más antiguo, podría hacer: $ sed 's / [XZ] [XZ] [XZ] [XZ] * / / g' inputfile donde X es una pestaña y Z es un espacio.
Marnix A. van Ammers
10
sed 's/[ \t]*/"space or tab"/'
Zac
fuente
2
¿Se garantiza que esto funcione en cualquier versión de sedcualquier sistema? Si no, podría valer la pena mencionar dónde funciona esto de manera similar a las otras respuestas, solo para que conozcamos las limitaciones y dónde esto podría no tener el resultado deseado.
Mokubai
2
Este RE es lo que uso para hacer coincidir los espacios en blanco. Es más simple que las clases de caracteres solo para coincidir con tabulación o espacio. Utiliza solo las convenciones más básicas de expresiones regulares, por lo que debería funcionar en cualquier lugar con una implementación funcional de expresiones regulares.
Nate
3
En Mac 10.9.5 esto coincide para espacios y 't'. Usé el anterior de Michael Douma para que coincida con los espacios en blanco (también funciona con -e).
Alien Life Form
No funciona con sensatez en mi sistema SUSE. Coincide con el primer lugar en la línea donde hay cero o más espacios, que está antes del primer carácter. Dudo que esa sea la función prevista, y ciertamente no fue el caso de uso solicitado. Creo que desea cambiar el '*' por '\ +' (o '\ {3, \}' según la pregunta) y tal vez poner ag al final del comando sed para que coincida con todas las ocurrencias del patrón. Reemplazar [\ t] con [[: espacio:]] también puede ser deseable, en caso de que haya algo más para el espacio en blanco en la línea.
jbo5112