在 Shell 脚本中连接列并从文本文件创建复合键

在 Shell 脚本中连接列并从文本文件创建复合键

我一直在尝试在 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 的列)的文件中创建一个 Composite。

请帮忙

答案1

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

相关内容