Bash
用bash中另一個文件中的值替換一個文件中的值
我有
List.csv
以下格式的 csv 文件命名:Location,IP Address,Host Name,Domain,Domain Name, User Name,Manufacturer,Model,System Type, Serial Number, Operating System,RAM (GB),Processor Type,Processor Frequency H1,xx.xx.xx.xx,PC1,domain.com,DOMAIN,User1,LENOVO,4089AZ8,X86-based PC,L90RA96,Microsoft Windows 7 Professional ,2,Pentium(R) Dual-Core CPU E5800,3.20GHz H3,xx.xx.xx.xx,PC2,domain.com,DOMAIN,User2,LENOVO,4089AZ8,X86-based PC,L906W3P,Microsoft Windows 7 Professional ,2,Pentium(R) Dual-Core CPU E5800,3.20GHz H2,xx.xx.xx.xx,PC3,domain.com,DOMAIN,User3,LENOVO,4089A76,X86-based PC,L929410,Microsoft Windows 7 Professional ,2,Pentium(R) Dual-Core CPU E5400,2.70GHz H2,xx.xx.xx.xx,PC4,domain.com,DOMAIN,User4,Hewlett-Packard,Z800,x64-based PC,SGH007QT16,Microsoft Windows 7 Professional ,12,Intel(R) Xeon(R) CPU W5590,3.33GHz
如果您查看該
MODEL
列,它包含一些不解釋模型名稱的值。我創建了另一個文件 ,model-list.csv
其中包含這些值及其對應的模型名稱。它看起來像:Manufacturer,Value,Model Name Lenovo, 4089AZ8, ThinkCentre Lenovo, 4089A76, ThinkCentre HP, Z800, HP Z800 Workstation
我希望將
List.csv
文件中的值替換為model-list.csv
. 由於文件中有 2900 多個項目List.csv
和大約 150 個項目model-list.csv
,我打算使用 bash 腳本來實現這一點,如下所示:#!/bin/bash file1="List.csv" file2="model-list.csv" outfile="List_out.csv" stagingfile="List-staging.csv" rm -f "$outfile" "$stagingfile" while read line do ModelNo=`echo "$line"|awk -F',' '{print $2}'` ModelName=`echo "$line"|awk -F',' '{print $3}'` cat "$file1"|grep ",$ModelNo," > "$stagingfile" if [ -s "$stagingfile" ] then while read line1 do NewLine=`echo "$line1"|sed "s/,${ModelNo},/,${ModelName},/g"` echo "$NewLine" >> "$outfile" done < "$stagingfile" rm -f "$stagingfile" fi done < "$file2"
執行上述腳本時,
"$outfile"
與List.csv
.劇本有什麼問題嗎?
您可以
awk
為此使用:awk -F',|, ' 'NR==FNR{a[$2]=$3} NR>FNR{$8=a[$8];print}' OFS=',' "$file2" "$file1"
這會讀取 model-list.csv,將所有模型及其描述儲存到字元串索引數組(例如
a["Z800"] == "HP Z800 Workstation"
)中。然後它讀取列表數據,用數組中的描述字元串替換每個模型。解釋:
-F',|, '
- 這使用正則表達式模式設置欄位分隔符,在這種情況下,欄位分隔符將是單個逗號,或單個逗號和單個空格。NR==FNR{a[$2]=$3}
- NR 是一個 awk 內部變數,它跟踪自程序開始以來讀取的總行數。FNR 類似,但跟踪目前文件已讀取的行數。一個 awk 習語也是如此NR==FNR
,意思是“如果這是要讀取的第一個文件”,相關的操作是a[$2]=$3
將欄位 3 的值保存在數組a
中,字元串索引設置為欄位 2 的值。NR>FNR{$8=a[$8];print}'
- 與前麵類似,但這次只對第一個被讀取的文件以外的文件進行操作。對於每一行,我們使用欄位 8 的值作為索引來查找數組中的值,然後將欄位 8 重新分配給數組值。最後,列印整行。OFS=',' "$file2" "$file1"
- 將輸出欄位分隔符設置為逗號(預設為空格),然後按指定順序讀入 2 個文件。