我有兩個 CSV 檔案 data1.csv 和 data2.csv 內容是這樣的(帶標題):
資料1.csv
Client Name;strnu;addr;fav
MAD01;HDGF;11;V PO
CVOJF01;HHD-;635;V T
LINKO10;DH--JDH;98;V ZZ
資料2.csv
USER;BINin;TYPE
XXMAD01XXXHDGFXX;11;N
KJDGD;635;M
CVOJF01XXHHD;635;N
問題 :
- DATA1.csv的第一列和第二列的值隨機存在于DATA2.csv的第一列。例如
MAD01;HDGF,存在于 DATA2 的第一列***MAD01***HDGF**(*可以是字母數字和/或符號字符),并且MAD01;HDGF可能USER與 DATA2 的列中的順序不同。 - DATA1中strnum的值等于DATA2中BINin列的值
- fav DATA1 列與 DATA2 中的 TYPE 相同,因為
V T = M并且V PO = N(可能存在其他一些值,但我們不需要它們,例如 DATA1 的第 3 行,它應該被忽略)
注意:一些資料可能存在于一個檔案中,但不存在于另一個檔案中。
我的 bash 腳本需要生成一個新的 CSV 檔案,其中應包含:
USER來自 DATA2的列Client Namestrnu從DATA1BINin僅當它等于strnuDATA1的相應行和值時才來自 DATA2TYPE使用Format并MN確保遵守以下條件V T = MV PO = N
我嘗試的第一件事是使用 grep 搜索兩個檔案中都存在的行
#!/bin/sh
DATA1="${1}"
DATA2="${2}"
for i in $(cat $DATA1 | awk -F";" '{print $1".*"$2}' | sed 1d) ; do
grep "$i" $DATA2
done
結果 :
$ ./script.sh DATA1.csv DATA2.csv
MAD01;HDGF;11;V PO
XXMAD01XXXHDGFXX;11;N
CVOJF01;HHD-;635;V T
LINKO10;DH--JDH;98;V PO
使用 grep 和 awk 我可以找到 DATA1 和 DATA2 檔案中存在的行,但它不適用于所有行,我猜這是因為-DATA1 的第 2 列中存在 和其他特殊字符,但可以忽略它們。
我不知道如何生成一個新的 csv 來混合兩個檔案中存在的行,但預期生成的 CSV 應該如下所示
USER;Client Name;strnu;BINin;TYPE
XXMAD01XXXHDGFXX;MAD01;HDGF;11;N
CVOJF01XXHHD;CVOJF01;HHD-;635;M
uj5u.com熱心網友回復:
這可以在單個 awk 程式中完成。這是join.awk
BEGIN {
FS = OFS = ";"
print "USER", "Client Name", "strnu", "BINin", "TYPE"
}
FNR == 1 {next}
NR == FNR {
strnu[$1] = $2
next
}
{
for (client in strnu) {
strnu_pattern = strnu[client]
gsub(/-/, "", strnu_pattern)
if ($1 ~ client && $1 ~ strnu_pattern) {
print $1, client, strnu[client], $2, $3
break
}
}
}
接著
awk -f join.awk DATA1.csv DATA2.csv
產出
USER;Client Name;strnu;BINin;TYPE
XXMAD01XXXHDGFXX;MAD01;HDGF;11;N
CVOJF01XXHHD;CVOJF01;HHD-;635;N
uj5u.com熱心網友回復:
假設/理解:
- 忽略欄位不是or之一的
DATA1.csv行favV TV PO - 匹配欄位時,我們需要忽略欄位中的任何連
DATA1.csv字符 - 匹配欄位時,來自的字串
DATA1.csv可以以任一順序顯示在DATA2.csv - 預期輸出的最后一行顯示以
635,N
一個 awk 想法:
awk '
BEGIN { FS=OFS=";"
print "USER","Client Name","strnu","BINin","TYPE" # print new header
}
FNR==1 { next } # skip input headers
FNR==NR { if ($4 == "V PO" || $4 == "V T") { # only process if fav is one of "V PO" or "V T"
cnames[FNR]=$1 # save client name
strnus[FNR]=$2 # save strnu
}
next
}
{ for (i in cnames) { # loop through array indices
cname=cnames[i] # make copy of client name ...
strnu=strnus[i] # and strnu so that we can ...
gsub(/-/,"",cname) # strip hypens from both ...
gsub(/-/,"",strnu) # in order to perform the comparisons ...
if (index($1,cname) && index($1,strnu)) { # if cname and strnu both exist in $1 then index()>=1 in both cases so ...
print $1,cnames[i],strnus[i],$2,$3 # print to stdout
next # we found a match so break from loop and go to next line of input
}
}
}
' DATA1.csv DATA2.csv
這會產生:
USER;Client Name;strnu;BINin;TYPE
XXMAD01XXXHDGFXX;MAD01;HDGF;11;N
CVOJF01XXHHD;CVOJF01;HHD-;635;N
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/536832.html
標籤:狂欢awk
