Wie ersetze ich einen Spaltenwert in einer Datei beim Vergleich mit einer anderen Datei?
Ich habe zwei Dateientest1.csvUndtest2.csv; Ich muss die empdep
Spalte ersetzen intest1.csvwenn es den Wert hat als"Zeichen*"Die zweite Dateitest2.csvhat den nötigen Wert, um das zu ersetzen"Zeichen*".
Hinweis: Ich verwende ksh
undtest1.csvhat rund 2.048.576 Zeilen undtest2.csvhat 10.000 Zeilen.
test1.csv
empname,place,empdep
aaaa,city1,001
bbbb,city2,sign-1
dddd,city1,005
ffff,city5,sign-2
hhhh,city7,sign-1
test2.csv
empname,new
aaaa,001
bbbb,002
cccc,003
dddd,005
eeee,006
ffff,007
gggg,008
hhhh,009
Erwartetes Ergebnis:
empname,place,empdep
aaaa,city1,001
bbbb,city2,002
dddd,city1,005
ffff,city5,007
hhhh,city7,009
Antwort1
Mit 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
Antwort2
Dies ist eine einfache Möglichkeit:
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
Antwort3
Verwenden Sie ksh
und sed
. Verwenden Sie sed
zum Parsentest2.csvund bevölkern Sie eineassoziatives Array ${new[@]}
. Dann durchlaufentest1.csvund VerwendungMustersubstitutionum die gewünschten Ausgaben auszudrucken:
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
Ausgabe:
empname,place,empdep
aaaa,city1,001
bbbb,city2,002
dddd,city1,005
ffff,city5,007
hhhh,city7,009
Hinweis: In diesem Fall haben die Eingabedateien keine Anführungszeichen und der Code ist ohne Anführungszeichen optisch einfacher. Wenn eine der Eingabedateien Leerzeichen enthält (oder enthalten könnte), werden die oben genannten Variablenmusszitiert werden.
Antwort4
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 und csv-sqlite sind vonhttps://github.com/mslusarz/csv-nix-tools