我有一个包含很多行的文件,如下所示:
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,其含义如下:
RS=<null>
告诉 awk 您的输入是一组由空行分隔的记录(即段落)。-F'\n'
告诉 awk 输入字段由换行符分隔(相当于-v FS='\n'
)。OFS='\t'
告诉 awk 输出字段必须以制表符分隔。$1=$1
告诉 awk 重新编译当前记录,用 OFS(制表符)替换字段之间的每个 FS(换行符)。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'