Bash

提取文件以生成和重命名差異文件

  • January 21, 2022

我有一個 csv(其中第一列和第二列由“,”分隔)文件,如下所示:

Column1,Column2
4e,info1
4t,info2
45t,info3
3,info4

我想獲得 4 個不同的文件,每行一個,文件名取自 Column1,而內容來自 Column2。

我的預期輸出是:

文件名1 =4e.smi

info1

文件名2 =4t.smi

info2

文件名3 =45t.smi

info3

文件名4 =3.smi

info4

我認為我可以生成兩個不同的變數,一個與第一列相關,另一個與第二列相關,並使用此變數為所有行循環創建新文件。但是我嘗試了這個 cmd 行,但它沒有用:

while IFS=',' read -r name smile; do write "$smile" "$name".smi; done < InputFIle.txt

有人可以幫我解決這個問題嗎?

謝謝。

write除了命令不是您要使用的命令這一事實之外,您的循環幾乎是正確的。相反,使用printf重定向。您還需要確保跳過初始行,我們可以通過多種不同的方式執行此操作。下面,我使用的是tail -n +2,但您也可以使用sed 1d.

tail -n +2 InputFIle.txt |
while IFS=, read -r name string; do
   printf '%s\n' "$string" >"$name".smi
done

請注意,這假設文件名僅寫入一次,就好像您在兩行或多行的第一列中具有相同的值一樣,後面的行將導致已寫入文件的數據被覆蓋。因此,您可能希望更改>附加到>>輸出文件。如果您想執行程式碼兩次(否則您將在輸出中獲得重複的數據),此更改將要求您另外刪除文件。

一種可能更有效的方法是awk像這樣使用:

awk -F, 'NR > 1 { print $2 >($1 ".smi") }' InputFIle.txt

這會將第二個逗號分隔的欄位列印到第一個欄位給出的文件名。NR它通過針對 1 進行測試(到目前為止讀取的記錄數)來跳過初始行。

這不會遇到與 shell 循環相同的問題。輸出文件將在第一個print到它時被截斷(清空或創建),然後將附加後續輸出。

如果您在某些行上有更多欄位,則awk需要修改變體以列印除第一個欄位之外的所有欄位:

awk -F, 'NR > 1 { name = $1; sub("[^,]*,",""); print >(name ".smi") }' InputFIle.txt

這會將第一個欄位保存在一個單獨的變數中name,然後從原始行中刪除該欄位sub()。然後它將剩餘的行列印到文件中。

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