Awk

使用 sed 或 awk 重新格式化文本

  • October 25, 2021

我有一個輸入,比如第一行是標題,是否可以將文本重新格式化為下面的輸出?

awk '{if ($2=="b" || $3 == "c" || $4 == "d" || $5 == "e" || $6 == "f" || $7 == "g" || $8 == "9" )'}' 

我在上面嘗試了不起作用,我是 Linux 的新手,任何想法都將不勝感激。

輸入 :

Name    Date          Time          Mxam     Mxterm
Maxus   Date:su,mo    Time:12,3:00  mxam:20  Mxterm:10
Feros   Time:12,3:00  Mxterm:19
Michel  Mxterm:16       

期望的輸出

Name    Date           Time              Mxam     Mxterm
Maxus   Date:su,mo     Time:12,3:00      mxam:20  Mxterm:10
Feros                  Time:12,3:00               Mxterm:19
Michel                                            Mxterm:16

GNU AWK:

awk -v IGNORECASE=1 '
FNR==1  {n = split($0, col)}
       {printf("%s ", $1); k=2
       for(i=2; i<=n; i++)
               printf("%s ", $0 ~ "\\<"col[i]"\\>"?$(k++):"")
       print ""}
' file | column -ts' '

IGNORECASE=1-忽略模式中的大小寫

column -ts' '-輸入分隔符是一個空格字元,這大大簡化了 awk 中的程序。

GNU SED:

sed -r '
s/\s+/ /g
1{h;b};G
:1;s/( \S*)(:\S*)(.*)\1/\3\1\2/i;t1
s/\n\S*//
:2;s/ [^: ]+( |$)/ \1/;t2
' file | column -ts' '

第一個標題行添加到每一行,由\n分隔符分隔。除第一列外,左側的列替換右側的相應列。沒有:符號的其餘列將替換為空格。

調試 sed 腳本的建議:

添加-n標誌sed -nr並將l命令放在 3 行末尾 - 1{h;b};G;l。執行腳本,然後重複所有 4 行,依此類推。l命令 - 顯示緩衝區的內容(模式空間)和緩衝區的錨端$

$$ awk updated $$:

awk '
NR==1   {n = split($0, col)}
       {k=1; for(i=1; i<=n; i++)
               printf( "%s ", $0 ~ "\\<"col[i]?$(k++):"")
       print ""}
' file | column -ts' '

將適用於初始標題匹配,但最好編寫完整的標題(例如insert_job days_somthing start_somting window term max_run_alarm must_somthing)並使用詞尾錨點"\\<"col[i]"\\>"

如果第一列從不為空並且使用唯一名稱作為標識符,那麼您可以保持原樣:

awk '
NR==1   {n = split($0, col)}
       {printf("%s ", $1); k=2
       for(i=2; i<=n; i++)
               printf("%s ", $0 ~ "\\<"col[i]?$(k++):"")
       print ""}
' file | column -ts' '

col[]- 具有列名的數組;col[1] == "Name"; col[2] == "Date"; col[3] == "Time"等等。"\\<"- 詞開始錨。範例 -"\\<"col[2]相等"\\<Date"

三元運算符 -condition expression ? statement1 : statement2

當條件表達式返回 true 時,statement1 被執行;否則執行語句 2。

$0 ~ "\\<"col[i]?$(k++):""- 因此,如果目前行$0包含"\\<"col[2],則下一個欄位$(k++)按照它出現在目前行的順序(例如$2in $0)列印,如果不是,則為空欄位""

$$ awk updated2 $$:刪除尾隨空格。

awk '
NR==1   {n = split($0, col)}
       {printf("%s ", $1); k=2
       for(i=2; i<=n; i++)
           printf("%s%c", ($0~"\\<"col[i]?$(k++):""), (n>i?OFS:ORS))}
' file | column -ts' '

$$ awk update3 $$:用於重新排列欄位。

awk '
NR==1   {n = split($0, col)}
       {k=1; for(i=1; i<=n; i++)
               A[i] = ($0~"\\<"col[i]?$(k++):"")
       for(i in A) $i = A[i]
       }
1' file | column -ts' '

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