es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo actualizar un campo delimitado por varios caracteres en un archivo en bash?

Estoy tratando de coincidir con un campo específico y actualizar sus datos desde un archivo delimitado con múltiples caracteres. Estoy usando esto para crear una imitación del comando UPDATE de SQL. Esto es parte de un proyecto más grande para crear un mini DBMS con bash.

Lo que intenté:

sed "s/\^\_\^/:/g" $file_path | cut -d: -f1 | grep -nw SAR | sed "s/\^\_\^/:/g" | cut -d: -f2 | sed -i "s/$match/$update/g"

Mi problema es que no puedo usar sed -i para actualizar solo las columnas específicas encontradas, ya que no se puede usar tuberías con este comando.

El delimitador que se está utilizando es ^_^.

Ejemplo del archivo de datos:

'EGP'^_^'Egypt'
'SAR'^_^'Europe'
'SAR'^_^'Europe'
'SAR'^_^'Europe'
'SAR'^_^'Europe'
'Europe'^_^'SAR'
'SAR'^_^'Europe'
'MYR'^_^'Malaysia'
'MYR'^_^'Malasia'

Mi $match puede ser SAR, por ejemplo, y $update sería USD.

Cambio esperado en el archivo de datos:

'EGP'^_^'Egypt'
'USD'^_^'Europe'
'USD'^_^'Europe'
'USD'^_^'Europe'
'USD'^_^'Europe'
'Europe'^_^'SAR'
'USD'^_^'Europe'
'MYR'^_^'Malaysia'
'MYR'^_^'Malasia'

Si hay un enfoque diferente que sea mejor, también es bienvenido, ya que soy bastante nuevo en la programación en bash.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema es que sed -i no funciona con tuberías porque requiere un argumento de archivo. Una forma de solucionar esto es usar un archivo temporal para almacenar los datos actualizados antes de sobrescribir el archivo original. Aquí hay una versión actualizada del script:

    #!/bin/bash
    
    file_path="data_file.txt"
    match="SAR"
    update="USD"
    
    # crea un archivo temporal para almacenar los datos actualizados
    tmp_file=$(mktemp)
    
    # reemplazar el delimitador por ":" y extraer columnas
    cat "$file_path" | tr '^_^' ':' \
      | awk -F: -v match="$match" -v update="$update" '$1 == match { $1 = update } { print }' \
      > "$tmp_file"
    
    # sobrescribe el archivo original con los datos actualizados
    mv "$tmp_file" "$file_path"
    

    En esta versión del script, usamos tr para reemplazar el delimitador ^_^ por : para que podamos extraer fácilmente las columnas usando awk. Dentro de awk, usamos la opción -v para pasar las variables match y update. Usamos $1 == match para coincidir solo con las filas donde la primera columna coincide con $match, y luego establecemos $1 en $update para esas filas antes de imprimir todas las columnas. Finalmente, redirigimos la salida a un archivo temporal y luego sobrescribimos el archivo original con los datos actualizados usando mv.

Comments are closed.