比較兩個文件,如果列相同,則用某個值替換下一列

比較兩個文件,如果列相同,則用某個值替換下一列

與另一個文件相比,如何替換文件中的列值?

我有兩個文件測試1.csv測試2.csv;我需要更換該empdep測試1.csv如果它的值為“符號*”。第二個文件測試2.csv具有替換該值所需的值“符號*”

注意:我正在使用ksh測試1.csv大約有 2,048,576 行測試2.csv有 10000 行。

測試1.csv

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

測試2.csv

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

預期結果:

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

答案1

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

答案2

這是一種簡單的方法:

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

答案3

使用kshsed.用於sed解析測試2.csv並填充一個關聯數組 ${new[@]}。然後循環遍歷測試1.csv並使用模式替換列印所需的輸出:

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

輸出:

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

注意:在本例中,輸入檔案沒有引號,沒有引號的程式碼在視覺上更簡單。若任一輸入檔包含(或可能包含)空格,則上述變數必須被引用。

答案4

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 和 csv-sqlite 來自https://github.com/mslusarz/csv-nix-tools

相關內容