Convierta la entrada basada en filas a columna basada en shell
-
27-10-2019 - |
Pregunta
Necesito su ayuda en una entrada de múltiples filas en diferentes columnas. Y haga lo mismo con todas las entradas en el archivo.
Ejemplo de archivo (mostrando solo 2 entradas, hay muchas como estas):
>ABC
*
AGA-AUUCUC-CGGUUCAAUCU
|||
UCUAUAACCGCGCCGAGUUAGU
>ABC
*
AGAUAU-GCUGCAGGCUCAAUUG
||||||
UCUAUAACCGCG-CCGAGUUAGU
Se requiere formato de archivo:
>ABC AGA-AUUCUC-CGGUUCAAUCU UCUAUAACCGCGCCGAGUUAGU
>ABC AGAUAU-GCUGCAGGCUCAAUUG UCUAUAACCGCG-CCGAGUUAGU
Puedo convertir la entrada única en formato requerido por:
tr '\n' '\t' <test3 | awk '{print $1,$3,$5}'
Pero, ¿cómo lo hago con todas las entradas leyendo todo el archivo?
Solución
Creo que estabas en el camino correcto con tu original awk
solución. Prueba esto; Creo que es una buena combinación de legible y efectivo:
awk 'BEGIN { RS="\n\n" } ; { print $1, $3, $5 }' < myfile
La idea es decirle a AWK que trate las líneas en blanco (2 nuevas líneas consecutivas) como separadores de registros. Luego, cada estrofa se trata como un solo registro, y el espacio en blanco (en este caso, una sola nueva línea) separa los campos. Esto es bastante similar a lo que estabas haciendo con tr
, excepto ahora, AWK ejecutará todo el archivo procesando una estrofa a la vez.
Otros consejos
Puedes usar awk
como esto:
awk 'NR%2 { printf "%s%s", $0, (NR+1)%6 ? " " : "\n" }' < test
Explicación:
Necesitas saber estas dos cosas sobre awk
:
la sintaxis es
condition { commands }
, dóndecommands
se ejecutan sicondition
es verdadero (no cero).NR
es el número del registro actual (es decir, el número de línea), comenzando con 1.
Aquí, la condición es NR%2
, que no es cero para líneas impares. Por lo tanto, el comando se ejecuta solo para líneas impares, que son las que desea imprimir. Las líneas pares se descartan en silencio.
los printf
Imprimirá cada línea impar, seguida de un espacio o una nueva línea. Su entrada repite cada 6 líneas, y desea una nueva línea después de las líneas 5, 11, 17, etc.. Puede agregar 1 a cada uno de estos números para hacerlo divisible por 6, por lo que la fórmula (NR+1)%6
es 0 para estos números.
Asi que (NR+1)%6 ? " " : "\n"
evalúa un espacio para las líneas 1 y 3, y una nueva línea para la línea 5. Luego se repite para 7, 9 y 11; y así.
Aquí hay una forma de usar Perl:
perl -ne 'chomp; if($. % 2 == 1) { print $_, ($. % 6 == 5) ? "\n" : "\t" }'
Eso imprimirá las líneas del 1er, 3, 5, 7º, etc., del archivo. Después de las líneas 5, 11, 17, etc., imprimirá una nueva línea; Después de otras líneas, imprimirá solo una pestaña.
(Nota: Esto supone que hay exactamente una línea en blanco entre grupos sucesivos de cinco líneas. Si eso es no el caso, entonces aclare).