Shell-Script

連接列並從 Shell 腳本中的文本文件創建複合鍵

  • December 27, 2021

我一直在嘗試在我的 Shell 腳本中實現一個功能,但不知何故卡在了實現中,需要幫助。

Sample File - f1.txt

col1|col2|col3|rev|spt
A1|54|tyre|56.89|45.23
B1|54|pole|11.89|85.23
C1|54|ture|112.89|185.23

文件可以有任意數量的列,並且不是固定的。我想要實現的是->

Concatenate all the Columns in the File (Note- It can have any number of Columns) except the Columns- rev and spt

Whenever it Finds Column Name as rev or spot it shouldnot include in Concatenation.
Example-

Output-
KeyCol|rev|spot
A1~54~tyre|56.89|45.23
B1~54~pole|11.89|85.23
C1~54~ture|112.89|185.23

所以理想情況下,我想在任何具有任意數量列的文件中創建一個合成,除了名為 rev 和 spot 的列。

請幫忙

這是awk您可以使用的命令:

awk -F'|' 'NR==1 {OFS=FS; print "KeyCol", $(NF-1), $NF} NR > 1 {OFS="~"; LAST=$(NF-1) FS $NF; NF-=2; print $0 FS LAST}'

解釋

  • -F '|'表示輸入欄位分隔符是|.

  • NR==1表示只操作第一行。在第一行,僅列印第一個欄位的“KeyCol”,然後列印最後兩個欄位,並且OFS(輸出欄位分隔符)將是FS(輸入欄位分隔符),在您的情況下是|.

  • 在第一個 ( ) 之後的下一行NR > 1

    • OFS="~"表示新的輸出欄位分隔符將是~.
    • LAST=$(NF-1) FS $NF- 將最後兩個欄位保存在名為 的字元串變數中LAST,並用FS(輸入欄位分隔符)分隔它們。
    • NF-=2- 將欄位數 ( NF) 減少 2 以排除最後兩個欄位。
    • print $0 FS LAST
      • $0現在只包含第一個(NF-2)欄位。
      • 它會將它們分開列印OFS(在這種情況下,~
      • 後跟原來的FS(即|
      • 以及保存最後兩個欄位的變數 LAST。

輸出

awk -F'|' 'NR==1 {OFS=FS; print "KeyCol", $(NF-1), $NF} NR > 1 {OFS="~"; LAST=$(NF-1) FS $NF; NF-=2; print $0 FS LAST}' f1.txt
KeyCol|rev|spt
A1~54~tyre|56.89|45.23
B1~54~pole|11.89|85.23
C1~54~ture|112.89|185.23

注1

您可以將該OFS="~"行移動到行尾NR==1,因為這樣它將應用於所有下一個記錄,您不需要為每一行設置它。

awk -F'|' 'NR==1 {OFS=FS; print "KeyCol", $(NF-1), $NF; OFS="~"} NR > 1 {LAST=$(NF-1) FS $NF; NF-=2; print $0 FS LAST}'

筆記2

您可以創建一個 awk 腳本來自動化它。

$ cat composite.awk
BEGIN { FS = "|" }
NR == 1 {
 OFS=FS
 print "KeyCol", $(NF-1), $NF
 OFS="~"
} 
NR > 1 {
 LAST=$(NF-1) FS $NF
 NF-=2
 print $0 FS LAST
}

請注意,我添加了一個BEGIN設置 的部分FS,因此您不需要命令的-F '|'參數awk

然後使用腳本文件執行它。

$ awk -f composite.awk f1.txt                                                                                            
KeyCol|rev|spt
A1~54~tyre|56.89|45.23
B1~54~pole|11.89|85.23
C1~54~ture|112.89|185.23

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