Edo*_*IFP 4 bash awk field rows
我有一个由一些商业软件生成的文本文件,如下所示.它由括号分隔的部分组成,每个部分都有数百万个元素,但确切的值会从一个案例变为另一个案例.
(1
2
3
...
)
(11
22
33
...
)
(111
222
333
...
)
Run Code Online (Sandbox Code Playgroud)
我需要实现如下输出:
1; 11; 111
2; 22; 222
3; 33; 333
... ... ...
Run Code Online (Sandbox Code Playgroud)
我发现了一种复杂的方式:
执行sed操作得到
1
2
3
...
#
11
22
33
...
#
111
222
333
...
Run Code Online (Sandbox Code Playgroud)使用awk如下将文件拆分为几个子文件
awk -v RS="#" '{print > ("splitted-" NR ".txt")}'
Run Code Online (Sandbox Code Playgroud)使用sed再次从子文件中删除空格
sed -i '/^[[:space:]]*$/d' splitted*.txt
Run Code Online (Sandbox Code Playgroud)把所有东西加在一
paste splitted*.txt > out.txt
Run Code Online (Sandbox Code Playgroud)添加字段分隔符(在我的bash脚本中定义)
awk -v sep=$my_sep 'BEGIN{OFS=sep}{$1=$1; print }' out.txt > formatted.txt
Run Code Online (Sandbox Code Playgroud)我觉得这很糟糕,因为我循环了几百万行.即使返回时间非常好(约80秒),我也想找到一个完整的awk解决方案,但无法实现.就像是:
awk 'BEGIN{RS="(\\n)"; OFS=";"} { print something } '
Run Code Online (Sandbox Code Playgroud)
我发现了一些相关的问题,特别是用awk进行的一行到列的转换,但它假设括号之间有一定数量的行,我不能这样做.
任何帮助,将不胜感激.
使用GNU awk实现多字符RS和真正的多维数组:
$ cat tst.awk
BEGIN {
RS = "(\\s*[()]\\s*)+"
OFS = ";"
}
NR>1 {
cell[NR][1]
split($0,cell[NR])
}
END {
for (rowNr=1; rowNr<=NF; rowNr++) {
for (colNr=2; colNr<=NR; colNr++) {
printf "%6s%s", cell[colNr][rowNr], (colNr<NR ? OFS : ORS)
}
}
}
$ awk -f tst.awk file
1; 11; 111
2; 22; 222
3; 33; 333
...; ...; ...
Run Code Online (Sandbox Code Playgroud)