Text-Processing

如何在正則表達式中包含以字母“N”開頭但排除以“N/A”開頭的行

  • May 17, 2020

我有一個包含很多行的文件,如下所示:

Table
$0.10
100
1
10


Chair
$0.12
N/A
7
5


Desktop
$0.08
86
7
3


Door
$0.00
N/A
7
3

Nails
$0.10
N/A
7
5

Sofa
$0.07
100
7
3

Stool
$1.00
0
7
5

Natural wood
$0.00
99
7
20

Carpet
$0.10
100
7
3

我想合併以字母開頭的線條。所以輸出必須是:

Table   $0.10   100 1   10       
Chair   $0.12   N/A 7   5       
Desktop $0.08   86  7   3       
Door    $0.00   N/A 7   3       
Nails   $0.10   N/A 7   5    
Sofa    $0.07   100 7   3    
Stool   $1.00   0   7   5       
Natural wood    $0.00   99  7   20  
Carpet  $0.10   100 7   3

使用此命令sed -E ':a;N;/\n[A-M|a-z|O-Zo-z]/!s/\n/\t/;ta;P;D' file,我得到:

Table   $0.10   100 1   10       
Chair   $0.12   N/A 7   5       
Desktop $0.08   86  7   3       
Door    $0.00   N/A 7   3       Nails   $0.10   N/A 7   5    
Sofa    $0.07   100 7   3    
Stool   $1.00   0   7   5       Natural wood    $0.00   99  7   20  
Carpet  $0.10   100 7   3

那麼,如何在正則表達式中包含那些以字母“N”開頭但排除以“N/A”開頭的行?

這就是 awk 中存在段落模式的原因。這將在每個 UNIX 機器上的任何 shell 中使用任何 awk 工作:

$ awk -v RS= -F'\n' -v OFS='\t' '{$1=$1}1' file
Table   $0.10   100     1       10
Chair   $0.12   N/A     7       5
Desktop $0.08   86      7       3
Door    $0.00   N/A     7       3
Nails   $0.10   N/A     7       5
Sofa    $0.07   100     7       3
Stool   $1.00   0       7       5
Natural wood    $0.00   99      7       20
Carpet  $0.10   100     7       3

上面的一切都是慣用的 awk,這就是它的意思:

  1. RS=<null>告訴 awk 您的輸入是一組由空行(即段落)分隔的記錄。
  2. -F'\n'告訴 awk 輸入欄位由換行符分隔(相當於-v FS='\n')。
  3. OFS='\t'告訴 awk 輸出欄位必須用製表符分隔。
  4. $1=$1告訴 awk 重新編譯目前記錄,將欄位之間的每個 FS(換行符)替換為 OFS(製表符)。
  5. 1是一個真正的條件,它呼叫 awks 列印目前記錄的預設操作。

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