如何在每n列开始一个新行?

如何在每n列开始一个新行?

所以我有一个 20,000“列”长和 2 行的文本文件。数据看起来像这样:

  FP1 amp     FP1 lat     FP2 amp       FP2 lat    FP3 amp       FP3 lat      AF1 amp         AF1 lat 
  4.1         231         2.2           232        1.3            233         4.4             234

每隔 120 列左右,标题值会在第二行中重复使用不同的值。如何每 120 列分隔这些“列”,开始一个新行并继续执行此操作,直到文件末尾?

答案1

假设我们用 BSD 转置数据rs

$ rs -T
a b c d e f g h
1 2 3 4 5 6 7 8
[Ctrl-D][Enter]
a  1
b  2
c  3
d  4
e  5
f  6
g  7
h  8

现在我们将它作为两个长列,易于awk处理。我们可以扫描数据并从$1和累积一对字符串$2。每当NR所需行大小的模为零时,我们就会输出累积的字符串。

$ awk '{ hdrs = (hdrs ? hdrs OFS $1 : $1);
         vals = (vals ? vals OFS $2 : $2); }
       !(NR % 3) { print hdrs; print vals;
                   hdrs = vals = "" } 
       END { print hdrs; print vals; }'
a  1
b  2
c  3
d  4
e  5
f  6
g  7
h  8
[Ctrl-D][Enter]
a b c
1 2 3
d e f
4 5 6
g h
7 8

如果需要不同的输出形状,如下所示(以一致的模式单独包装标头和值),那么从 Awk 代码中删除它并不困难:

a b c
d e f
g h
1 2 3
4 5 6
7 8

好吧,现在实际数据很混乱,因为它的字段标题用多个空格分隔,并且它们本身包含空格。

假设字段仅包含单个内部空格,并且始终以多个空格分隔,我们可以做的是预处理数据以用非空白字符(数据中尚未出现)替换内部空格,例如作为波形符 ( ~)。例如使用 Sed:

$ sed -e 's/\([^ ]\) \([^ ]\)/\1~\2/g'
foo bar      xyzzy quux      alpha beta     gamma     delta
[Ctrl-D][Enter]
foo~bar      xyzzy~quux      alpha~beta     gamma     delta

过滤回来很容易

tr '~' ' '

相关内容