Compare dos archivos, si las columnas son iguales, reemplace la siguiente columna con algún valor

Compare dos archivos, si las columnas son iguales, reemplace la siguiente columna con algún valor

¿Cómo reemplazo el valor de una columna en un archivo en comparación con otro archivo?

tengo dos archivosprueba1.csvyprueba2.csv; Necesito reemplazar la empdepcolumna enprueba1.csvsi tiene el valor como"firmar*". El segundo archivoprueba2.csvtiene el valor necesario para reemplazar eso"firmar*".

Nota: estoy usando kshyprueba1.csvtiene alrededor de 2.048.576 filas yprueba2.csvtiene 10000 filas.

prueba1.csv

empname,place,empdep
aaaa,city1,001
bbbb,city2,sign-1
dddd,city1,005
ffff,city5,sign-2
hhhh,city7,sign-1

prueba2.csv

empname,new
aaaa,001
bbbb,002
cccc,003
dddd,005
eeee,006
ffff,007
gggg,008
hhhh,009

Resultado Esperado:

empname,place,empdep
aaaa,city1,001
bbbb,city2,002
dddd,city1,005
ffff,city5,007
hhhh,city7,009

Respuesta1

Con awk:

awk '
  BEGIN{ FS=OFS="," } # set input/output field separator to `,`
  NR==FNR{            # if this is the first file `test2.csv`
    a[$1]=$2          # store field2 in array `a` using field1 as index
    next              # continue with next line
  } 
  $3 ~ /^sign/{       # if field3 of `test1.csv` begins with `sign`
    $3=a[$1]          # replace the field with array value (index of field1)
  }
  1                   # print the line
' test2.csv test1.csv

Respuesta2

Esta es una forma sencilla:

for i in $(cat text1.csv)  
do  
    name=$(echo $i | cut -d',' -f1)   
    empdep=$(echo $i | cut -d',' -f3)  
    newvalue=$(grep $name text2.csv | cut -d',' -f2)    
    if [[ $empdep = sign* ]]    
    then  
        sed -n "s/^$name,\(.*\),.*/$name,\1,$newvalue/pg" text1.csv  
    else  
        echo $i  
    fi  
done

Respuesta3

Usando kshy sed. Usar sedpara analizarprueba2.csvy poblar unmatriz asociativa ${new[@]}. Luego recorraprueba1.csvy usesustitución de patronespara imprimir los resultados deseados:

typeset -A new $(sed -n '2,${s/^/new[/;s/,/]=/p}' test2.csv)
while IFS=, read a b c; do echo $a,$b,${c/#sign*/${new[$a]}}; done < test1.csv

Producción:

empname,place,empdep
aaaa,city1,001
bbbb,city2,002
dddd,city1,005
ffff,city5,007
hhhh,city7,009

Nota: En este caso, los archivos de entrada no tienen comillas y el código es visualmente más simple sin comillas. Si alguno de los archivos de entrada contiene (o podría contener) espacios, las variables anterioresdebeser citado.

Respuesta4

csv-merge -N t1 -p test1.csv -N t2 -p test2.csv | 
csv-sqlite -T 'select t1.empname, t1.place, case when t1.empdep like "sign%" then t2.new else t1.empdep end as empdep
from t1 left join t2 on t1.empname = t2.empname'

csv-merge y csv-sqlite son dehttps://github.com/mslusarz/csv-nix-tools

información relacionada