Tengo un archivo de texto con 4 columnas delimitado por comas.
Como estoy leyendo cada registro en un bucle, quiero agregar un valor a la 5ª columna, dependiendo de una condición.
Por lo que si sé el número de fila y el número de columna, ¿cómo puedo usar awk/sed comandos para reemplazar/establece el valor en ese campo en particular sin el uso de archivos temporales?
Quiero actualizar el archivo (directamente) que estoy leyendo de

inp.txt
a,b,c,d
e,f,g,h
i,j,k,l

Gracias,
-sri

4 Comentarios

  1. 2

    No puedo hablar por sed, pero el propósito de awk no está para editar archivos en un lugar, pero para escribir en la salida estándar.

    Pero de todos modos, he aquí una solución que no necesita un bucle para, pretendiendo que la condición es que la entrada en la columna 4 es un h.

    awk -F ',' '{ if ($4 == "h") print $0",z"; else print $0","}' inp.txt > out.txt

    de salida:

    a,b,c,d,
    e,f,g,h,z
    i,j,k,l,
    • Lo anterior podría escribirse de forma más concisa como: awk -F ',' '{print $0 FS ($4 == "h" ? "z" : "")}' inp.txt > out.txt
  2. 2

    No se puede editar directamente el archivo con awk o sed. Algunas versiones de sed tiene una opción (-i) que funciona con un archivo temporal y sobrescribe el archivo original, pero en realidad no editar el archivo en su lugar. Esto no es una gran cosa. Basta hacer:

    $ awk 'NR==5{ $(NF+1) = "new value"}1' OFS=, FS=, input-file > tmp.$$
    $ mv tmp.$$ input-file

    Para agregar una nueva columna hasta la fila 5 de input-file. Si lo desea, puede utilizar ed para editar el archivo, pero tiene más sentido utilizar un archivo temporal. Si quieres pretender que usted no utiliza un archivo temporal, y su sed soporta -i, usted puede hacer lo mismo con:

    sed -i '5s/$/,new value/' input-file

    Aunque la mayoría de las utilitites no permitir que en lugar de la modificación del archivo, es simple de usar uno de los siguientes sh funciones para emular que el comportamiento de uso de archivos temporales:

    edit() { local f=$1; shift; "[email protected]" < $f > $f.$$ && mv $f.$$ $f; }  # Break hard links
    edit() { local f=$1; shift; "[email protected]" < $f > $f.$$ && cat $f.$$ > $f && rm $f.$$; }

    Con cualquiera de estos, usted podría utilizar awk para dar la apariencia de edición de archivos en lugar de usar edit filename awk awk-cmds. La primera versión se rompe enlaces duros, pero utiliza un poco menos IO.

  3. 1
    perl -i -F, -lane 'if($.==<row number>){$F[<column_number>-1]+=<add your stuff here>}print join(",",@F)' your_file

    probado a continuación:

    >cat temp
    b,c,d,g
    r,g,d,s

    ejecutar para cambiar la 3ª columna en la segunda fila:

    >perl -i -F, -lane 'if($.==2){$F[2]=10}print join(",",@F)' temp
    > cat temp
    b,c,d,g
    r,g,10,s
  4. 0

    Te refieres a como esta?
    esta es la versión no utilizar los archivos temporales.

    [[email protected] ~]$ cat tmp | sed 's_^\(.*\),\(.*\),\(.*\),\(.*\)_,,,_g' 
    inp.txt
    a,b,c,d
    e,f,g,h
    i,j,k,l
    
    [[email protected] ~]$ cat tmp | sed 's_^\(.*\),\(.*\),\(.*\),\(.*\)_,sth,,_g'
    inp.txt
    a,sth,c,d
    e,sth,g,h
    i,sth,k,l
    
    [[email protected] ~]$ sed -ie 's_^\(.*\),\(.*\),\(.*\),\(.*\)_,sth,,_g' tmp
    [[email protected] ~]$ cat tmp
    inp.txt
    a,sth,c,d
    e,sth,g,h
    i,sth,k,l

    Saludos,

    • Se ESTÁ utilizando un archivo temporal. Revise su sed de documentación.
    • Gracias. He aprendido una cosa nueva.

Dejar respuesta

Please enter your comment!
Please enter your name here