
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 mv
el archivo de salida con el nuevo nombre input.txt
, eso debería sobrescribir el archivo de entrada (use una barra diagonal \mv
para evitar el alias del mv
comando).
NOTA: probablemente puedas obtener el mismo resultado con instrucciones awk más cortas, pero esta sintaxis lo hace más legible. sed
Probablemente 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 awk
script, 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 bash
secuencias 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])