答案1
使用 GNU ,您可以通过设置insideawk
来指定遍历数组的顺序。在本例中,将其设置为强制按值的升序遍历数组。sorted_in
PROCINFO
@val_str_asc
接下来将第一行拆分为一个数组,a
最后,对于每一行,遍历数组并在检索到键时打印与键对应的字段。
awk -F'/' 'BEGIN{PROCINFO["sorted_in"]="@val_str_asc"};
FNR == 1{n = split($0, a)};
{x=0; for (k in a) printf "%s%s", $k, ++x == n? "\n": FS}' file
apple/banana/mango/orange
onion/potato/garlic/tomato
carpet/chair/window/table
或者,与python
from __future__ import print_function
with open('file') as f:
keys = next(f).rstrip('\n').split('/')
print(*sorted(keys), sep='/')
for line in f:
g = (m for l, m in sorted(zip(keys, line.rstrip('\n').split('/'))))
print(*g, sep='/')
apple/banana/mango/orange
onion/potato/garlic/tomato
carpet/chair/window/table
答案2
我认为基本方法是
创建一个索引列表,按第一行的顺序排序 - 例如,如下所述:如何在 Perl 中返回排序列表的索引?
使用列表对行进行切片
所以
perl -F'/' -alne '
our @inds = sort { $F[$a] cmp $F[$b] } 0..$#F if $. == 1;
print join "/", @F[@inds]
' file
答案3
在 BSD 上实用rs
程序:
$ rs -T -c'/' <data.in | sort | rs -T -C'/' >data.out
-T
转置-c'/'
设置输入列分隔符-C'/'
设置输出列分隔符
看着它:
$ cat data.in
banana/orange/apple/mango
potato/tomato/onion/garlic
chair/table/carpet/window
$ cat data.out
apple/banana/mango/orange/
onion/potato/garlic/tomato/
carpet/chair/window/table/
去掉/
最后多余的部分:
$ sed 's#/$##' data.out
apple/banana/mango/orange
onion/potato/garlic/tomato
carpet/chair/window/table
答案4
使用GNU
datamash
,转置,排序,并且转置再次:datamash -t '/' transpose < file | datamash -t '/' -s -g1 transpose
输出:
apple/banana/mango/orange onion/potato/garlic/tomato carpet/chair/window/table
各种各样的软件工具:
join -a 1 -t / -o $( head -n 1 file | \ tr / '\n' | \ nl -n ln | \ sort -k2 | \ cut -f1 | \ sed -n 's/^/1./;H;1h;${x;s/\n/,/g;s/ //gp}' ) \ file /dev/null
工作原理:
join
可以通过传递给其选项的参数对列进行重新排序-o
。因此(不使用变量和数组)技巧是生成这些参数:head
得到第一行,tr
将其转换为几行,- 哪些
nl
数字, sort
由第二列,(即苹果, ETC。),- 以及
cut
第 1 列中重新排序的数字列表, sed
将数字转换为join
喜欢的格式。