Tengo una línea larga en la que quiero insertar un espacio cada 4 caracteres, en una sola línea de texto sólido para que sea más fácil de leer, ¿cuál es la forma más sencilla de hacerlo? También debería poder ingresar la línea desde una tubería. p.ej
echo "foobarbazblargblurg" | <some command here>
da
foob arba zbla rgbl urg
command-line
shell
text-processing
xenoterracida
fuente
fuente
sed
que intenté primero que podía patearme.'s/.\{4\}/& /g;s/ $//'
Puede usar el siguiente ejemplo simple:
fuente
sed
respuesta. No lo sabíafold
antes.fold
, no funciona con caracteres de varios bytes (comoecho €€€€€€€€ | fold -w4 | paste -sd' ' -
en UTF-8).Aquí está el ejemplo usando
grep
yxargs
:fuente
xargs
se ejecutaecho
de forma predeterminada, por lo que no funcionará con palabras como-nen
o que contengan barras diagonales inversas dependiendo de laecho
implementación. Verá el extraño carácter de nueva línea de vez en cuando también si xargs ejecuta más de unoecho
. Mejor canalizar a supaste -sd ' ' -
lugar. Tenga en cuenta que-o
no es una opción estándar.Solo en bash, no hay comandos externos:
o como una versión de tubería de una línea:
La forma en que esto funciona es convertir cada carácter de la cadena en un "(.)" Para la coincidencia de
=~
expresiones regulares y capturar , y luego generar las expresiones capturadas de laBASH_REMATCH[]
matriz, agrupadas según sea necesario. Los espacios iniciales / finales / intermedios se conservan, elimine las comillas"${BASH_REMATCH[@]:1}"
para omitirlos.Aquí está envuelto en una función, esta procesará sus argumentos o leerá stdin si no hay argumentos:
Puede parametrizar fácilmente el recuento para ajustar la cadena de formato en consecuencia.
Se agrega un espacio final, use dos
printf
s en lugar de uno si eso es un problema:El primero
printf
imprime (hasta) los primeros 4 caracteres, el segundo imprime condicionalmente todo el resto (si corresponde) con un espacio inicial para separar los grupos. La prueba es para 5 elementos, no 4 para dar cuenta del elemento cero.Notas:
printf
s'%c
podría ser utilizado en lugar de%s
,%c
(tal vez) hace más clara la intención, pero no es multi-byte carácter seguro. Si su versión de bash es capaz, lo anterior es seguro para todos los caracteres de varios bytes.printf
reutiliza su cadena de formato hasta que se quede sin argumentos, por lo que solo engulle 4 argumentos a la vez y maneja los argumentos finales (por lo que no se necesitan casos extremos, a diferencia de algunas de las otras respuestas aquí que posiblemente sean incorrectas)BASH_REMATCH[0]
es toda la cadena coincidente, por lo que solo la salida comienza desde el índice 1printf -v myvar ...
en su lugar para almacenar en una variablemyvar
(sujeto al comportamiento habitual de bucle de lectura / subshell)printf "\n"
si es necesarioPuede hacer que lo anterior funcione
zsh
si usa la matriz enmatch[]
lugar deBASH_REMATCH[]
, y restar 1 de todos los índices, yazsh
que no mantiene un elemento 0 con toda la coincidencia.fuente
Con
zsh
solo:O
con
ksh93
solo:Con cualquier shell POSIX solamente (también evitando el espacio final si la longitud de entrada es un múltiplo de 4):
Ahora, eso es para los personajes . Si desea hacerlo en grupos de grafemas (por ejemplo, para romper
Stéphane
, escrito como$'Ste\u0301phane'
, comoStép hane
y noSte phan e
), conzsh
:Con ksh93, también podría dividir el ancho de la pantalla, lo que funcionaría para lo
Stéphane
anterior, pero también podría ayudar cuando intervienen otros tipos de caracteres de ancho cero o doble ancho:fuente
Voy a responder solo insertando espacios según sea necesario para que aparezca un espacio al menos después de cada 4 caracteres en una línea; No estoy seguro de qué manera quiere manejar este caso. Por ejemplo, dada la entrada de "aa bbccdd", obtendría la salida "aa bbcc dd" en lugar de "aa b bccd d".
Estoy usando Perl para mirar hacia adelante, pero no estoy muy familiarizado con Perl en general, por lo que es posible que se necesiten ajustes:
fuente
He hecho esto usando Python
Primero estoy leyendo el archivo, luego estoy dividiendo entre 4 caracteres y agregando espacio
/root/l.txt ==> Consiste en el contenido que proporcionó en el ejemplo
salida
fuente