Primeros dos campos separados por _ y el rest de los campos tal como están

#CHROM POS REF ALT ../S101_sorted.bam ../S102_sorted.bam ../S105_sorted.bam ../S107_sorted.bam ../S113_sorted.bam ../S114_sorted.bam ../S115_sorted.bam ../S Aradu.A01 296611 TCTTTTTTTTTTTTTTT/CTT/CTTTT Aradu.A01 326689 TCT/CTTTT/CTTTT/CT/CTTTTTTTT/CT/CTT Aradu.A01 615910 TGTTTTTTTTTTTTTTTTTTT TT Aradu.A01 661394 TATTTTTT/ATTTTTTTTTTTTTTT Aradu.A01 941674 CTCC/TCCC/TCCCCCCCCCCCCCCCC Aradu.A01 942064 CTC/TC/TC/TC/TC/TCCC/TCC/TC/TCCC/TC/TCCCCC/TC/T Aradu.A01 954858 GAG/AGGGGGGGGGGGGGGGG/AGGGG Aradu.A01 1196780 CAC/ACCCCCCCCCCC/ACCC/ACCCCCC 

Tengo un file en el formatting anterior e bash imprimir las primeras dos columnas separadas por _ y el rest de las columnas tal como están. Intenté la siguiente tuerca de secuencia de commands awk , no devuelve ninguna salida.

 awk '{if (NR>1) print $1"_"$2; for(i=3;i<NF;i++) printf "\t", $i}' input_file > out_file. 

¿Puede alguien sugerir por favor qué estoy haciendo mal aquí?

Para cambiar el espacio en blanco entre las dos primeras columnas a un guión bajo, sugiero sed :

  sed -e 's/[\t ]\+/_/' 

Y si tuviera que ignorar la línea del encabezado:

 sed -e '/^#/! s/[\t ]\+/_/' 

o, para el caso más general (el encabezado puede comenzar con cualquier char; \t funciona solo con gnu sed )

 sed -E '1! s/[[:blank:]]+/_/' 

En cuanto a la pregunta sobre su código awk , la primera print , probablemente debería ser una print para que no se imprima una nueva línea cronometrada.

A partir de su código, esto debería darle el resultado deseado:

 awk ' NR>1 { printf( $1"_"$2 ); for (i=3;i<NF;i++) printf("\t%s", $i); printf("\n") } NR==1 { print } ' input > output 

Esto parece funcionar:

 awk '{ if(NR>1) { printf $1"_"$2; for(i=3;i<NF;i++) {printf "\t"$i } } print "" }' input 

Aquí hay un pequeño script de Python 3, que hace el trabajo. La premisa subyacente aquí es leer cada carácter de línea por carácter. Utiliza dos variables, una que rastrea si se han escrito los guiones bajos de la primera a la segunda, y otra, que rastrea si se nos permite sustituir el espacio por subrayado.

Me di count desde el formatting de file de input de OP que la segunda columna es todos los valores numéricos. Por lo tanto, podemos comenzar por permitir que los espacios sean sustituidos por guiones bajos, pero una vez que hemos escrito guiones bajos y encontrado un carácter numérico (siendo ambas condiciones verdaderas), podemos desactivar la variable write_ok y los otros espacios se imprimirán como siempre.

 #!/usr/bin/env python3 import sys import os def count_first_spaces(string): write_ok = True underscores_ok = False for char in string: if char == " " and write_ok: print("_",end="") underscores_ok = True continue if underscores_ok and char.isdigit(): write_ok = False print(char,end="") print("") # add newline def main(): if not os.path.isfile(sys.argv[1]): sys.exit(1) with open(sys.argv[1]) as fd: for line in fd: if line.startswith('#'): print(line.strip()) else: count_first_spaces(line.strip()) if __name__ == '__main__': main() 

Y aquí está la ejecución de testing:

 $ ./add_underscore.py input.txt #CHROM POS REF ALT ../S101_sorted.bam ../S102_sorted.bam ../S105_sorted.bam ../S107_sorted.bam ../S113_sorted.bam ../S114_sorted.bam ../S115_sorted.bam ../S Aradu.A01_______296611 TCTTTTTTTTTTTTTTT/CTT/CTTTT Aradu.A01_______326689 TCT/CTTTT/CTTTT/CT/CTTTTTTTT/CT/CTT Aradu.A01_______615910 TGTTTTTTTTTTTTTTTTTTT TT Aradu.A01_______661394 TATTTTTT/ATTTTTTTTTTTTTTT 

Si desea que los datos se guarden en un file diferente, ejecútelo como ./add_underscore.py input.txt > output.txt