Perl 有条件地用列名替换单元格值
我有一个165 x 165的秩矩阵,这样每一行的值都在1-165之间。我想解析每一行并删除所有>=5的值,按递增顺序对每一行进行排序,然后用原始矩阵中的列名称替换值1-5Perl 有条件地用列名替换单元格值,perl,sed,awk,Perl,Sed,Awk,我有一个165 x 165的秩矩阵,这样每一行的值都在1-165之间。我想解析每一行并删除所有>=5的值,按递增顺序对每一行进行排序,然后用原始矩阵中的列名称替换值1-5 例如,对于k行,值1、2、3、4、5将在前两次转换后产生,并将被p、d、m、n、a替换。我假设您的数组由数组组成 Awk、Sed或Perl都没有多维数组。但是,可以使用数组的数组在Perl中模拟它们 $a[0]->[0] = xx; $a[0]->[1] = yy; [...] $a[0]->[164] =
例如,对于k行,值1、2、3、4、5将在前两次转换后产生,并将被p、d、m、n、a替换。我假设您的数组由数组组成 Awk、Sed或Perl都没有多维数组。但是,可以使用数组的数组在Perl中模拟它们
$a[0]->[0] = xx;
$a[0]->[1] = yy;
[...]
$a[0]->[164] = zz;
$a[1]->[0] = qq;
$a[1]->[1] = rr;
[...]
$a[164]->[164] = vv;
这有意义吗
我正在调用行$x
和列$y
,因此数组中的元素将是$array[$x]->[$y]
。那好吗
for my $x (1..164) { #First row is column names
for my $y (0..164) {
if ($array[$x]->[$y] <= 5) {
$array[$x]->[$y] = $array[0]->[$y];
}
}
}
好的,您的列名将在$array[0]
行中,因此如果我们在$array[$x]->[$y]
中找到小于5的值,我们知道列名在$array[0]->[$y]
中。那好吗
for my $x (1..164) { #First row is column names
for my $y (0..164) {
if ($array[$x]->[$y] <= 5) {
$array[$x]->[$y] = $array[0]->[$y];
}
}
}
对于我的$x(1..164){#第一行是列名
我的$y(0..164){
如果($array[$x]->[$y][$y]=$array[0]->[$y];
}
}
}
我只是检查所有的行,对于每一行,所有的列,并检查值。如果值小于或等于5,我用列名替换它
我希望我不是在为你做功课。这个GNU-sed解决方案可能会工作,但它需要放大,因为我只使用10x10矩阵进行测试:
# { echo {a..j};for x in {1..10};do seq 1 10 | shuf |sed 'N;N;N;N;N;N;N;N;N;s/\n/ /g';done; }> test_data
# cat test_data
a b c d e f g h i j
4 5 9 3 6 2 10 8 7 1
3 7 4 2 1 6 10 5 8 9
10 9 3 1 2 7 8 5 6 4
5 10 4 9 7 8 1 3 6 2
8 6 5 9 1 4 3 2 7 10
2 8 9 3 5 6 10 1 4 7
3 9 8 2 1 4 10 6 7 5
3 7 2 1 8 6 10 4 5 9
1 10 8 3 6 5 4 2 7 9
7 2 3 5 6 1 10 4 8 9
# cat test_data |
sed -rn '1{h;d};s/[0-9]{2,}|[6-9]/0/g;G;s/\n|$/ &/g;s/$/&1 2 3 4 5 /;:a;s/^(\S*) (.*\n)(\S* )(.*)/\2\4\1\3/;ta;s/\n//;s/0[^ ]? //g;:b;s/([1-5])(.*)\1(.)/\3\2/;tb;p'
j f d a b
e d a c h
d e c j h
g j h c a
e h g f c
h a d i e
e d a f j
d c a h i
a h d g f
f b c h d
sed
命令的工作原理如下
数据文件的第一行包含列标题,存储在保留空间中,然后是模式空间(当前行)已删除。对于所有后续数据行,所有两个或多个数字和值6到9都转换为0。列名将被追加,并在数据值中添加换行符。换行符和字符串结尾之前插入空格。数据将转换为查找,并在其前面添加排序值,即1 2 3 4 5。换行符与任何0值和关联的查找一起删除。值1到5将替换为查找中的列名
编辑:
我可能误解了有关列或行排序的问题,如果是这样的话,这是一个最小的解决方案-用原始值替换
1 2 3 4 5
,并在用查找中的列名替换数字数据之前执行数字排序。您的输入数据看起来如何?我想=5
应该读>5
GNU awk4.0也有。Dimitre-谢谢你让我知道。刚刚看到David的评论。不,你没有帮我做作业,但非常感谢你的建议