¿Qué comando (s) alimentará un archivo de texto delimitado por tabulaciones y cortará cada línea a 80 caracteres?


8

Tengo archivos de texto de varias líneas de datos (a veces) delimitados por tabuladores. Me gustaría generar el archivo para poder echarle un vistazo, por lo que me gustaría ver solo los primeros 80 caracteres de cada línea (diseñé el archivo de texto para poner primero las cosas importantes en cada línea).

Pensé que podría usar cat para leer cada línea del archivo y enviar cada línea al siguiente comando en una tubería:

cat tabfile | cut -c -80

Pero eso parecía roto. Intenté hacer un poco de juego, y grep parecía funcionar, pero luego descubrí que no, no lo hizo (no todas las líneas del archivo tenían más de 80 caracteres), parece que las pestañas se cuentan como caracteres individuales por corte.

Lo intenté:

cat tabfile | tr \t \040 | cut -c -80

Aunque eso alteraría un poco mis datos, al eliminar la legibilidad de los espacios en blanco. Pero eso no funcionó. Tampoco lo hizo:

cat tabfile | tr \011 \040 | cut -c -80

Tal vez estoy usando tr mal? He tenido problemas con tr antes, queriendo eliminar múltiples espacios (parece que la versión de tr a la que tengo acceso en esta máquina tiene una opción -s para apretar varios caracteres; es posible que deba jugar más)

Estoy seguro de que si me equivoco podría usar perl, awk o sed, o algo para hacer esto.

Sin embargo, me gustaría una solución que utilice comandos regulares (POSIX?), Para que sea lo más portátil posible. Si termino usando tr, probablemente intente convertir las pestañas en caracteres, tal vez haga un cálculo, corte el cálculo y luego vuelva a convertir esos caracteres en pestañas para la salida.

No necesita ser una sola línea / ingresada directamente en la línea de comando; un script está bien.


Más información sobre archivos de pestañas:

Utilizo la pestaña para dividir campos, porque algún día querré importar datos en algún otro programa. Así que tiendo a tener solo una pestaña entre las piezas de contenido. Pero también utilizo pestañas para alinear cosas con columnas verticales, para ayudar en la legibilidad al mirar el archivo de texto sin formato. Lo que significa que, para algunos fragmentos de texto, relleno el final del contenido con espacios hasta llegar a donde funcionará la pestaña para alinear el siguiente campo con los que están arriba y debajo.

DarkTurquoise # 00CED1 Mares, cielos, botes de remos Naturaleza
MediumSpringGreen # 00FA9A Útil para árboles Magic  
Lima # 00FF00 Solo para uso en pollos de primavera y fru $

¿Entonces quieres 80 caracteres contando el ancho de la pestaña? Puede reemplazar las pestañas con un recuento apropiado de espacios, luego usar cortar
muru

Annnnnd, ¿cómo puedo (fácilmente) expandir un solo personaje con varios caracteres? O, lo que es más importante, con una cantidad variable de caracteres (dependiendo de cuántos otros caracteres hay en la línea), ya que uso la pestaña para alinear cosas verticalmente con diferentes cantidades de información antes / después de cada pestaña. Como dije, si quisiera aprender perl / awk / sed, estoy seguro de que podría, pero me gustaría algo simple
user3082

Usted podría tratar prde coreutils: pr -1 -t -l200 -W80 file. Aumente / disminuya la longitud de la página (número después -l) según su necesidad.
don_crissti

Don, tu sugerencia (¿por qué no es una respuesta?) Me da un buen mensaje de error. Pero el hombre dice "pr - imprimir archivos", así que investiga eso.
user3082

Don, haz de esto una respuesta y hablemos allí. Tengo algo que se parece mucho al tuyo, en su mayoría el mismo formato, en su mayoría los mismos indicadores: -w en lugar de -W, etc ...
user3082

Respuestas:


9

Creo que estás buscando expandy / o unexpand. Parece que está tratando de asegurarse de que un \tancho ab cuente como 8 caracteres en lugar del único. foldtambién lo hará, pero ajustará su entrada a la siguiente línea en lugar de truncarla. Creo que quieres:

expand < input | cut -c -80

expandy unexpandse especifican ambos POSIX :

  • La expandutilidad escribirá los archivos o la entrada estándar en la salida estándar con \tcaracteres ab reemplazados por uno o más caracteres de espacio necesarios para rellenar la siguiente tabulación. Cualquier carácter de retroceso se copiará en la salida y hará que se disminuya el recuento de posición de columna para los cálculos de tabulación; el recuento de la posición de la columna no se disminuirá por debajo de cero.

Bastante simple. Entonces, aquí hay un vistazo a lo que esto hace:

unset c i; set --;                                                             
until [ "$((i+=1))" -gt 10 ]; do set -- "$@" "$i" "$i"; done                      
for c in 'tr \\t \ ' expand;  do eval '                                           
    { printf "%*s\t" "$@"; echo; } | 
      tee /dev/fd/2 |'"$c"'| { 
      tee /dev/fd/3 | wc -c >&2; } 3>&1 |
      tee /dev/fd/2 | cut -c -80'
done

El untilbucle en la parte superior obtiene un conjunto de datos como ...

1 1 2 2 3 3 ...

Es printfesto con el %*sindicador de relleno arg para que cada uno de los que están en el conjunto printfrellene con tantos espacios como sea posible en el número del argumento. A cada uno le agrega un \tcarácter ab.

Todos los tees se utilizan para mostrar los efectos de cada filtro a medida que se aplica.

Y los efectos son estos:

1        2        3        4        5        6        7        8                9               10
1  2   3    4     5      6       7        8         9         10 
1  2   3    4     5      6       7        8         9         10 
66
1        2        3        4        5        6        7        8                9               10
1        2        3        4        5        6        7        8                9               10 
1        2        3        4        5        6        7        8                
105

Esas filas están alineadas en dos conjuntos como ...

  1. salida de printf ...; echo
  2. salida de tr ...oexpand
  3. salida de cut
  4. salida de wc

Las cuatro filas superiores son los resultados del trfiltro, en el que cada \tab se convierte en un solo espacio .

Y los últimos cuatro los resultados de la expandcadena.


1
En realidad, no me importa (demasiado) si el \ t se cuenta como 8 (5?) O uno, solo que no se cuenta como uno y se muestra como 8.
user3082

+ @ anon3202: tiene mucho sentido. Entiendo lo que quieres decir - (y la longitud de tabulación es una opción cli, por cierto) - Simplemente no lo dije tan bien como podría haberlo dicho. Espero que entiendas lo esencial, como supongo que podrías tener.
mikeserv

No seguí la explicación, pero hacer un monton con expansiones muestra que expandir es definitivamente lo que estaba buscando.
user3082

3

Dado que las pestañas son más de alineación que de delimitación, una forma podría ser usar columny luego cut:

column -s '\t' -t <some-file | cut -c -80

Parece columnque no es POSIX. Es parte de las utilidades BSD en Ubuntu, así que supongo que es bastante multiplataforma.


Usando columnesta forma, OP ni siquiera necesitaría agregar espacios manualmente para alinearse.
Beni Cherniavsky-Paskin

1

La sugerencia de Don en los comentarios fue un buen comienzo.

Esto es lo que necesitaba para que funcione (principalmente):

pr +1 -1 -t -m -l1000 -w 80 tabfile

El -mera necesaria para que el -wefecto de la bandera de toma en una sola columna. La página de manual podría usar alguna reescritura para indicar eso.

Al intentar una solución alternativa, descubrí que prgenera \tcaracteres, por lo que alimentar sus resultados cutdio como resultado el mismo problema.

-1 (la bandera de la columna) dice específicamente en la página del manual:

Esta opción no debe usarse con -m.

Sin embargo, sin esta opción, las prlíneas se truncan willy-nilly, a una longitud mucho más corta que la especificada.

prtambién inserta un espacio antes (¿o después?) de cada palabra en un campo (es decir, cada lugar donde tengo un solo espacio, tiene dos después del procesamiento). Si hay demasiadas palabras, los espacios insertados ignoran la -wrestricción (creando un ajuste). Pero, curiosamente, las `` columnas '' que no están delimitadas por tabuladores (es decir, dispuestas en espacios en blanco) permanecen alineadas.



0

Una utilidad que debería ser verdaderamente consciente del ancho de pantalla es fold: desafortunadamente, no parece tener una opción para descartar en lugar de envolver. Aunque probablemente sea terriblemente ineficiente, sin embargo, podría hacer algo como

while read -r line; do fold -w80 <<< "$line" | head -n1; done < file
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.