2012-03-23 7 views
7

suponer que tengo una cadenaCómo reemplazar la n-ésima columna/campo en una cadena separada por comas usando sed/awk?

"1,2,3,4" 

Ahora quiero reemplazar, por ejemplo, el tercer campo de la cadena por un valor diferente.

"1,2,NEW,4" 

me las arreglé para hacerlo con el siguiente comando:

echo "1,2,3,4" | awk -F, -v OFS=, '{$3="NEW"; print }' 

Ahora el índice de la columna que se sustituyó debe pasarse como una variable. Entonces en este caso

index=3 

¿Cómo puedo pasar esto a awk? Porque esto no funcionará:

echo "1,2,3,4" | awk -F, -v OFS=, '{$index="NEW"; print }' 
echo "1,2,3,4" | awk -F, -v OFS=, '{$($index)="NEW"; print }' 
echo "1,2,3,4" | awk -F, -v OFS=, '{\$$index="NEW"; print }' 

¡Gracias por su ayuda!

Respuesta

5

que el shell interpolar el índice en el programa awk:

echo "1,2,3,4" | awk -F, -v OFS=, '{$'$index'="NEW"; print }' 

Nota cómo el programa awk citado inicialmente solo se divide en tres partes, un solo principio citado '{$', el valor del índice interpolado, seguido por el resto del programa citado una sola vez.

+1

Puede usar '-v var = valor' para definir una variable dentro de awk a través de su línea de comandos y luego usar' $ var'. Por lo tanto, este truco de sustitución de texto no es necesario. – Kaz

-1

Con awk simple (I.E. No es boquiabel, etc.) Creo que tendrá que usar split(string, array, [fieldsep]); cambiar la entrada de la matriz de su elección y luego unirlos de nuevo junto con sprintf o similar en un bucle.

gawk le permite tener una variable como nombre de campo, $ index en su ejemplo. Ver here.

gawk es por lo general el awk por defecto en Linux, por lo que cambiar su invocación a curiosear "guión" y ver si funciona.

4

Esto podría funcionar para usted:

index=3 
echo "1,2,3,4" | awk -F, -v OFS=, -v INDEX=$index '{$INDEX="NEW"; print }' 

o:

index=3 
echo "1,2,3,4" | sed 's/[^,]*/NEW/'$index 
1

Aquí está una manera uctive sed para romper el awk wardness:

$ echo "1,2,3,4" | sed 's/,/\n/g' | sed -e $index's/.*/NEW/' 

Esto es fácilmente extensible a múltiples índices simplemente agregando otro -e $newindex's/.*/NEWNEW/'

+0

¿Cómo puedo convertir las líneas nuevas en una lista separada por comas? Probé sed/\ n /,/g 'pero eso no funcionará? –

+0

@PeterMeier, creo que no funciona porque 'sed' trata las líneas por separado ahora, no como texto completo. Después de haber visto [esta respuesta] (http://stackoverflow.com/a/6539865/1258041), sugiero que el resultado de la salida sea 'paste -sd ',' 'como este:' echo "1,2,3,4 "| sed 's /,/\ n/g' | sed -e $ index's /.*/ NEW/'| pegar -sd ',' '. –

0
# This should be faster than awk or sed. 
str="1,2,3,4" 
IFS=',' 
read -a f <<< "$str" 
f[2]='NEW' 
printf "${f[*]}" 
Cuestiones relacionadas