Editar archivos con script de shell

Editar archivos con script de shell

Estoy desarrollando un script y realiza cálculos que debo incluir en un archivo de texto ya completado. El formato de las líneas del archivo es:

1 20/10/16 12:00 take car in the garage joe's garage

Dentro del script obtengo un número de los cálculos y ese número reemplazará el primer número de la fila. Por ejemplo, el "calcular" devuelve el valor 15, luego el script debe acceder al archivo en cuestión y cambiar la fila en cuestión debería quedar así:

15 20/10/16 12:00 take car in the garage joe's garage

El caso es que no sé cómo lograr este cambio. Puede estar en bash, awk, sed o cualquier recurso disponible. Gracias.

Respuesta1

Qué tal si:

awk -v old=$oldNum -v new=$newNum \
'{if ($1==old) {$1=new; print} else {print}}' input.txt > output.txt

Lo intenté así:

$ cat input.txt
2 19/10/16 15:30 some other line
1 20/10/16 12:00 take car in the garage joe's garage
3 17/10/16 5:30 another one

$ oldNum=2
$ newNum=15

Ejecute el comando awk, luego:

$ cat output.txt
15 19/10/16 15:30 some other line
1 20/10/16 12:00 take car in the garage joe's garage
3 17/10/16 5:30 another one

Es esto lo que querías ? Si desea que su resultado aparezca en el archivo original, solo mvel archivo de salida con el nuevo nombre input.txt, eso debería sobrescribir el archivo de entrada (use una barra diagonal \mvpara evitar el alias del mvcomando).

NOTA: probablemente puedas obtener el mismo resultado con instrucciones awk más cortas, pero esta sintaxis lo hace más legible. sedProbablemente pueda hacerlo de una manera aún más concisa.


EDITAR: Me doy cuenta de que esto funciona si desea cambiar solo 1 número dentro de su archivo. Si entiendo su problema correctamente, desea volver a calcular el número paracadalínea y cree un archivo con esos nuevos números. La forma óptima de hacerlo sería incluir el cálculo del nuevo número de líneaadentroel awkscript, de esa manera no tiene que crear un bucle de shell, lo cual generalmente es una mala idea ya que llamar a herramientas como awk, echo, sed... repetidamente termina siendo muy costoso. Podrías hacer algo como esto:

if [ -f $PWD/output.txt ]; then 
    # Remove old output if present in current directory
    \rm -f $PWD/output.txt
fi

awk '{ ###calculation here, result store in newNum###; $1=newNum; print}' input.txt > output.txt

Por ejemplo, si quiero incrementar trivialmente en uno cada número de línea:

awk '{$1++; print}' input.txt > output.txt

Si no puede (o no se atreve) a incluir su cálculo dentro awk, puede hacer un bucle en el archivo, pero eso es bastante torpe según lo que entiendo de bashsecuencias de comandos:

if [ -f $PWD/output.txt ]; then 
    # Remove old output if present in current directory
    \rm -f $PWD/output.txt
fi

while read line
do
    newNum=###Calculation here for current line###
    echo $line | awk -v new=$newNum '$1=new' >> output.txt
done <input.txt

Respuesta2

prueba esto..

awk -v num="$variable" '{$1=num}1' input.txt

Respuesta3

Aquí hay un breve script en Python que hace lo que usted quiere. El uso es simple: proporcione el archivo, el número con el que comienza la línea y el número que desea ver en su lugar.

Manifestación:

    bash-4.3$ datos del gato.txt
    2 19/10/16 15:30 alguna otra línea
    1 20/10/16 12:00 coger el coche en el garaje garaje de joe
    3 17/10/16 5:30 otro
    bash-4.3$ python renumerar.py datos.txt 1 15
    ['renumber.py', 'data.txt', '1', '15']
    bash-4.3$ datos del gato.txt
    2 19/10/16 15:30 alguna otra línea
    15 20/10/16 12:00 coger el coche en el garaje garaje de joe
    3 17/10/16 5:30 otro

Código:

import sys
import os

print(sys.argv)

with open(sys.argv[1]) as inputfile:
    with open('/tmp/temp.text','w') as tempfile:
         for line in inputfile:
             old = line.strip().split()
             if old[0] == sys.argv[2]:
                old[0] = sys.argv[3] 
                line = ' '.join(old) + '\n' 
             tempfile.write(line)

os.rename('/tmp/temp.text',sys.argv[1])

información relacionada