我需要比較兩個輸入檔案(file1.csv 和 file2.csv)并存盤結果和第三個檔案(file3.csv)。
條件如下:
- 如果條目與 file1 和 file2 匹配,則將其存盤在 file3 上
- 如果在 file1 上找到條目,則將其存盤在 file3 上
它看起來像這樣:
輸入:file1.csv
"switch10"
"switch33"
"router51"
"switch6"
"router44"
"router12"
"switch2"
輸入:file2.csv
"router51";"DatacenterA - cab1";"Prod - Tenant12"
"switch33";"DatacenterB - cab14";"Prod - Tenant4"
"switch2";"DatacenterA - cab3";"Dev - Tenant5"
"router44";"DatacenterC - cab2";"Test - Tenant2"
結果:file3.csv
"router12"
"router44";"DatacenterC - cab2";"Test - Tenant2"
"router51";"DatacenterA - cab1";"Prod - Tenant12"
"switch2";"DatacenterA - cab3";"Dev - Tenant5"
"switch6"
"switch10"
"switch33";"DatacenterB - cab14";"Prod - Tenant4"
我嘗試了很多使用 'awk' 的組合;但是我無法構造條件。
我想知道是否有人可以幫助我構建條件來構建這個結果 file3.csv。
非常感謝您的幫助。
uj5u.com熱心網友回復:
我會AWK按照以下方式使用 GNU 來完成這項任務,讓file1.txt內容成為
"switch10"
"switch33"
"router51"
"switch6"
"router44"
"router12"
"switch2"
和file2.txt內容是
"router51";"DatacenterA - cab1";"Prod - Tenant12"
"switch33";"DatacenterB - cab14";"Prod - Tenant4"
"switch2";"DatacenterA - cab3";"Dev - Tenant5"
"router44";"DatacenterC - cab2";"Test - Tenant2"
然后
awk 'BEGIN{FS=";"}(NR==FNR){arr[$1]=$0}((NR!=FNR)&&($1 in arr)){arr[$1]=$0}END{for(i in arr){print arr[i]}}' file1.txt file2.txt
輸出
"switch6"
"router12"
"router44";"DatacenterC - cab2";"Test - Tenant2"
"router51";"DatacenterA - cab1";"Prod - Tenant12"
"switch33";"DatacenterB - cab14";"Prod - Tenant4"
"switch10"
"switch2";"DatacenterA - cab3";"Dev - Tenant5"
免責宣告:我假設您能夠接受輸出檔案中的任何行順序。AWK說明:我通知GNU;用作欄位分隔符 ( FS),然后在處理第一個檔案 ( NR==FNR) 時,我arr通過將整個當前行 ( $0) 放在作為第一個欄位 () 內容的鍵下來填充陣列$1。NR!=FNR在處理下一個檔案arr(print處理完所有檔案后,我arr使用for.
(在 gawk 4.2.1 中測驗)
uj5u.com熱心網友回復:
與@Daweo 類似的想法,但:
- 使用提供的檔案名
- 腳本中的硬編碼檔案名而不是引數,因為它們不可互換
- 以請求的順序產生結果
您將腳本另存為task,chmod 755 task然后將其運行為./task > file3.csv:
#!/usr/bin/env -S awk -F; -f
BEGIN {
while ( getline <"file2.csv" ) {
lookup[$1] = $0
}
while ( "sort -k1.1,1.7 -k1.8n file1.csv" | getline ) {
print ($0 in lookup) ? lookup[$0] : $0
}
}
注意:這里使用的排序是脆弱的,因為它依賴于固定大小的前綴(路由器或交換機)來識別復合鍵的兩個部分。
使用 gawk 的 PROCINFO["sorted_in"] 功能以指定順序回傳鍵并使用自定義比較函式str_num_cmp()使其更加健壯:
#!/usr/bin/env -S awk -F; -f
function str_num_to_a(i, a) {
match(i, /"([^0-9]*)([0-9] )"/, a)
}
function str_num_cmp(i1, v1, i2, v2) {
str_num_to_a(i1, a1)
str_num_to_a(i2, a2)
if(a1[1] < a2[1])
return -1
if(a1[1] == a2[1]) {
if(a1[2] < a2[2])
return -1
if(a1[2] == a2[2])
return 0
}
return 1
}
BEGIN {
while ( getline <"file1.csv" ) {
keys[$1] = ""
}
while ( getline <"file2.csv" ) {
lookup[$1] = $0
}
PROCINFO["sorted_in"] = "str_num_cmp"
for (k in keys) {
print (k in lookup) ? lookup[k] : k
}
}
uj5u.com熱心網友回復:
在每個 Unix 機器上的任何 shell 中使用任何 awk 并假設您參考的欄位不包含;s 并且您不關心輸出順序:
$ cat tst.awk
BEGIN { FS=";" }
NR==FNR {
first[$1]
next
}
{
print
delete first[$1]
}
END {
for ( i in first ) {
print i
}
}
$ awk -f tst.awk file1.csv file2.csv
"router51";"DatacenterA - cab1";"Prod - Tenant12"
"switch33";"DatacenterB - cab14";"Prod - Tenant4"
"switch2";"DatacenterA - cab3";"Dev - Tenant5"
"router44";"DatacenterC - cab2";"Test - Tenant2"
"switch6"
"router12"
"switch10"
如果您確實關心輸出順序,則可以將 decorate/sort/undecorate 成語與任何 awk sort cut 一起使用:
$ cat tst.awk
BEGIN { FS=OFS=";" }
NR==FNR {
first[$1]
next
}
{
prt($0)
delete first[$1]
}
END {
for ( i in first ) {
prt(i)
}
}
function prt(str, arr, alpha, numeric) {
split(str,arr)
alpha = numeric = arr[1]
sub(/[0-9].*/,"",alpha)
gsub(/[^0-9]/,"",numeric)
print alpha, numeric, str
}
$ awk -f tst.awk file1.csv file2.csv | sort -t';' -k1,1 -k2,2n | cut -d';' -f3-
"router12"
"router44";"DatacenterC - cab2";"Test - Tenant2"
"router51";"DatacenterA - cab1";"Prod - Tenant12"
"switch2";"DatacenterA - cab3";"Dev - Tenant5"
"switch6"
"switch10"
"switch33";"DatacenterB - cab14";"Prod - Tenant4"
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/432867.html
上一篇:ELF部分識別
