如何在正则表达式中包含以字母“N”开头的行但排除以“N/A”开头的行

如何在正则表达式中包含以字母“N”开头的行但排除以“N/A”开头的行

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

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”开头的行?

答案1

这就是 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 重新编译当前记录,用 OFS(制表符)替换字段之间的每个 FS(换行符)。
  5. 1是调用 awks 打印当前记录的默认操作的 true 条件。

答案2

感谢 Steeldriver 的推荐,我找到了解决方案:

sed -E ':a;N;/\n[A-Za-z][^/]/!s/\n/\t/;ta;P;D'
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

答案3

可以用NR(记录数)来完成,但需要删除空行。

   sed '/^$/d' filename | awk '{ORS=(NR%5?FS:RS)}1'

相关内容