Valores separados por tabulaciones en awk


90

¿Cómo selecciono la primera columna de la cadena separada por TAB?

# echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F'\t' '{print $1}'

Lo anterior devolverá la línea completa y no solo "LOAD_SETTLED" como se esperaba.

Actualizar:

Necesito cambiar la tercera columna en los valores separados por tabulaciones. Lo siguiente no funciona.

echo $line | awk 'BEGIN { -v var="$mycol_new" FS = "[ \t]+" } ; { print $1 $2 var $4 $5 $6 $7 $8 $9 }' >> /pdump/temp.txt

Sin embargo, esto funciona como se esperaba si el separador es una coma en lugar de un tabulador.

echo $line | awk -v var="$mycol_new" -F'\t' '{print $1 "," $2 "," var "," $4 "," $5 "," $6 "," $7 "," $8 "," $9 "}' >> /pdump/temp.txt

4
awk 'COMIENZO {FS = "[\ t] +"}; {print $ 1} '# esto es lo que estaba buscando. ¿Es correcta mi búsqueda de Google? :)
— shantanuo

3
Gracias a este comentario, he descubierto: awk 'BEGIN {FS="\t"}; {print $1,FS,$2,FS,$3}' myFile.txtimprimir valores delimitados por tabulaciones de las tres primeras columnas.
— Wok

6
O quizás simplementeawk 'BEGIN {OFS="\t"}; {print $1,$2,$3}'
— Josiah Yoder

3
Tanto GNU como BSD awk admiten la -vconfiguración de variables. Es feo usarlo BEGIN {FS="\t"}dentro de un programa en línea , y es probable que se objete cualquier contribución de código abierto que intente hacer de esa manera. Solo haga eso si está escribiendo un archivo de programa . Además, se desaconseja usar en -Flugar de -v FS=porque este último deja claro que solo FSse está configurando y no OFS. La confusión sobre ese último punto es lo que causó esta publicación en primer lugar. Por eso es importante el "buen estilo".
— Bruno Bronosky

1
Por favor, nadie, nunca, debería hacer lo que demostró @Wok. No enumera los separadores de campo de [entrada] en su salida. Usted especifica un Separador de campo de salida a través de la OFSvariable.
— Bruno Bronosky

Respuestas:


141

Debe configurar la OFSvariable (separador de campo de salida) para que sea una pestaña:

echo "$line" | 
awk -v var="$mycol_new" -F $'\t' 'BEGIN {OFS = FS} {$3 = var; print}'

(asegúrese de citar la $linevariable en la declaración de eco)


6
¿Cuál es el propósito de $ en $ '\ t'?
— Amr Mostafa

10
Respondiendo a mi propia pregunta de la Advanced Bash Scripting Guide : La construcción de expansión de cadenas entre comillas $ '...' es un mecanismo que usa valores octales o hexadecimales de escape ..., por ejemplo, quote = $ '\ 042'.
— Amr Mostafa

5
@AmrMostafa, lástima que guía tiene una explicación engañosa que lleva a pensar que no lo hace la $de $'\t'que no se necesita. El wiki de Greg es mejor: "De estos, $'...'es el más común y actúa como comillas simples, excepto que las combinaciones con barra invertida se expanden según lo especificado por el estándar ANSI C".
— Cristian Ciupitu

9
En retrospectiva, $'\t'no es necesario. awk entiende que la cadena "\t"es un carácter de tabulación
— glenn jackman

5
Colaboradores de código abierto, les ruego que no envíen cosas como awk -F $'\t' 'BEGIN {OFS = FS} …'. Eso debería ser awk -v FS='\t' -v OFS='\t' '…'. Puede parecer pedante, pero ser inconsistente aumenta las posibilidades de que un colaborador posterior introduzca un error porque malinterpreta su código.
— Bruno Bronosky

21

¡Asegúrate de que sean realmente pestañas! En bash, puede insertar una pestaña usandoC-v TAB

$ echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F$'\t' '{print $1}'
LOAD_SETTLED


9

Utilizo las variables FSy OFSpara manipular archivos de zona BIND que están delimitados por tabulaciones. Aquí está uno de mis scripts https://gist.github.com/RichardBronosky/abe1652c2d5c78c35b92ad02bdf0d0af#file-dns_update-sh-L36-L39

La carne es:

awk -v FS='\t' -v OFS='\t' \
    -v record_type=$record_type \
    -v hostname=$hostname \
    -v ip_address=$ip_address '
$1==hostname && $3==record_type {$4=ip_address}
{print}
' $zone_file > $temp

Esta es una forma limpia y fácil de leer de hacer esto.


5
echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -v var="test" 'BEGIN { FS = "[ \t]+" } ; { print $1 "\t" var "\t" $3 }'

0

¿No debería funcionar esto?

echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk '{print $1}'
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.