Bash

用bash中另一個文件中的值替換一個文件中的值

  • February 13, 2019

我有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 個文件。

引用自:https://unix.stackexchange.com/questions/126485