Csv

切換 .csv 文件中的列,使它們都相同

  • April 13, 2015

我有 20 個具有6x6行和列的 excel 文件,其中第一行和第一列是字元串標題。這些文件中的每一個都有 4 個相同的列和行標題,除了 1 個不同。我想知道如何修改它們,以便每個文件中具有相同標題的列和行具有相同的順序,而不同的行和列將始終是最後一個。

例如:

如果a.csv看起來像這樣:

   a   b   d   c   x
a   1   2   3   5   3
b   2   2   5   5   2
d   2   3   4   4   6
c   5   5   6   6   5
x   3   1   6   7   9

b.csv看起來像這樣:

   d   c   b   a   y
d   2   3   6   5   3
c   5   2   6   6   5
b   6   4   2   3   4
a   6   4   4   6   2
y   5   3   6   7   9

c.csv看起來像這樣:

   a   c   d   b   z
a   3   3   5   5   2
c   5   4   6   6   1
d   7   4   5   7   2
b   3   2   6   6   7
z   5   3   6   4   7

依此類推….對於所有 20 個文件

這就是我希望他們看起來的樣子:

a.csv:

   a   b   c   d   x
a   1   2   5   3   3
b   2   2   5   5   2
c   5   5   6   6   5
d   2   3   4   4   6
x   3   1   7   6   9

b.csv:

   a   b   c   d   y
a   6   4   4   6   2
b   3   2   4   6   4
c   6   6   2   5   5
d   5   6   3   2   3
y   7   6   3   5   9

與 c.csv 和其餘的 excel 文件相同。

對於每次呼叫的任何固定排序(在您的範例中為 a、b、c、d),您可以使案例如這樣的awk程序來完成任務:

awk -v order=',a,b,c,d' '

BEGIN {
   OFS = FS = "\t"
   n = split(order,ord,",")
   for (i=1; i<=n; i++) ind[ord[i]] = i
}
FNR==1 {
   for (i=2; i<=n; i++) prm[ind[$i]] = i
}
{
   out[$1] = sprintf("%s", $1)
   for (i=2; i<=n; i++) {
       out[$1] = out[$1] sprintf("%s%s", OFS, $prm[i])
   }
   out[$1] = out[$1] sprintf("%s%s", OFS, $NF)
}
ENDFILE {
   for (i=1; i<=n; i++) print out[ord[i]]
   print out[$1] ORS
}

' a.csv b.csv c.csv

注意:由於這種情況,此程式碼假定 GNU awk 是最新版本 (4.x) ENDFILE。(如果這不可用,則解決方案需要調整。)

注意 2:如果您想單獨處理文件(每次awk呼叫一個數據文件),您可以替換ENDFILEEND(也將在較舊awk的 s 中執行)。

您的樣本數據的結果是:

   a   b   c   d   x
a   1   2   5   3   3
b   2   2   5   5   2
c   5   5   6   6   5
d   2   3   4   4   6
x   3   1   7   6   9

   a   b   c   d   y
a   6   4   4   6   2
b   3   2   4   6   4
c   6   6   2   5   5
d   5   6   3   2   3
y   7   6   3   5   9

   a   b   c   d   z
a   3   5   3   5   2
b   3   6   2   6   7
c   5   6   4   6   1
d   7   7   4   5   2
z   5   4   3   6   7

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