使用awk在矩阵中插入一行和一列
Insert a row and a column in a matrix using awk
我有一个矩阵形式的 250 行 x 300 列的网格化数据集:
ifile.txt
2 3 4 1 2 3
3 4 5 2 4 6
2 4 0 5 0 7
0 0 5 6 3 8
我想在第一列插入纬度值,在顶部插入经度值。看起来像:
ofile.txt
20.00 20.33 20.66 20.99 21.32 21.65
100.00 2 3 4 1 2 3
100.33 3 4 5 2 4 6
100.66 2 4 0 5 0 7
100.99 0 0 5 6 3 8
增量为0.33
我可以手动为小尺寸矩阵执行此操作,但我不知道如何以我想要的格式获得输出。我是按照下面的方式写的脚本,但是完全没用。
echo 20 > latitude.txt
for i in `seq 1 250`;do
i1=$(( i + 0.33 )) #bash can't recognize fractions
echo $i1 >> latitude.txt
done
echo 100 > longitude.txt
for j in `seq 1 300`;do
j1=$(( j + 0.33 ))
echo $j1 >> longitude.txt
done
paste longitude.txt ifile.txt > dummy_file.txt
cat latitude.txt dummy_file.txt > ofile.txt
与perl
$ perl -lane 'print join "\t", "", map {20.00+$_*0.33} 0..$#F if $.==1;
print join "\t", 100+(0.33*$i++), @F' ip.txt
20 20.33 20.66 20.99 21.32 21.65
100 2 3 4 1 2 3
100.33 3 4 5 2 4 6
100.66 2 4 0 5 0 7
100.99 0 0 5 6 3 8
-a
到 auto-split 输入空格,结果保存在 @F
数组中
- 有关命令行选项的详细信息,请参阅 https://perldoc.perl.org/perlrun.html#Command-Switches
if $.==1
为第一行输入
map {20.00+$_*0.33} 0..$#F
根据 @F
数组的大小进行迭代,对于每次迭代,我们根据 {}
中的等式得到一个值,其中 $_
将是 [= 20=、1
等直到 @F
数组的最后一个索引
print join "\t", "", map...
使用制表符分隔符打印空元素和地图结果
- 对于所有行,打印
@F
数组 pre-fixed 的内容以及 100+(0.33*$i++)
的结果,其中 $i
在数字上下文中最初将是 0
。同样,制表符在连接这些值时用作分隔符
如果需要格式化使用sprintf
,也可以初始化$,
而不是使用join
perl -lane 'BEGIN{$,="\t"; $st=0.33}
print "", map { sprintf "%.2f", 20+$_*$st} 0..$#F if $.==1;
print sprintf("%.2f", 100+($st*$i++)), @F' ip.txt
关注 awk
也可能对您有所帮助。
awk -v col=100 -v row=20 'FNR==1{printf OFS;for(i=1;i<=NF;i++){printf row OFS;row=row+.33;};print ""} {col+=.33;=;print col OFS [=10=]}' OFS="\t" Input_file
现在也添加上述解决方案的非一种线性形式:
awk -v col=100 -v row=20 '
FNR==1{
printf OFS;
for(i=1;i<=NF;i++){
printf row OFS;
row=row+.33;
};
print ""
}
{
col+=.33;
=;
print col OFS [=11=]
}
' OFS="\t" Input_file
Awk
解法:
awk 'NR == 1{
long = 20.00; lat = 100.00; printf "%12s%.2f", "", long;
for (i=1; i<NF; i++) { long += 0.33; printf "\t%.2f", long } print "" }
NR > 1{ lat += 0.33 }
{
printf "%.2f%6s", lat, "";
for (i=1; i<=NF; i++) printf "\t%d", $i; print ""
}' file
$ cat tst.awk
BEGIN {
lat = 100
lon = 20
latWid = lonWid = 6
latDel = lonDel = 0.33
latFmt = lonFmt = "%*.2f"
}
NR==1 {
printf "%*s", latWid, ""
for (i=1; i<=NF; i++) {
printf lonFmt, lonWid, lon
lon += lonDel
}
print ""
}
{
printf latFmt, latWid, lat
lat += latDel
for (i=1; i<=NF; i++) {
printf "%*s", lonWid, $i
}
print ""
}
$ awk -f tst.awk file
20.00 20.33 20.66 20.99 21.32 21.65
100.00 2 3 4 1 2 3
100.33 3 4 5 2 4 6
100.66 2 4 0 5 0 7
100.99 0 0 5 6 3 8
我有一个矩阵形式的 250 行 x 300 列的网格化数据集:
ifile.txt
2 3 4 1 2 3
3 4 5 2 4 6
2 4 0 5 0 7
0 0 5 6 3 8
我想在第一列插入纬度值,在顶部插入经度值。看起来像:
ofile.txt
20.00 20.33 20.66 20.99 21.32 21.65
100.00 2 3 4 1 2 3
100.33 3 4 5 2 4 6
100.66 2 4 0 5 0 7
100.99 0 0 5 6 3 8
增量为0.33
我可以手动为小尺寸矩阵执行此操作,但我不知道如何以我想要的格式获得输出。我是按照下面的方式写的脚本,但是完全没用。
echo 20 > latitude.txt
for i in `seq 1 250`;do
i1=$(( i + 0.33 )) #bash can't recognize fractions
echo $i1 >> latitude.txt
done
echo 100 > longitude.txt
for j in `seq 1 300`;do
j1=$(( j + 0.33 ))
echo $j1 >> longitude.txt
done
paste longitude.txt ifile.txt > dummy_file.txt
cat latitude.txt dummy_file.txt > ofile.txt
与perl
$ perl -lane 'print join "\t", "", map {20.00+$_*0.33} 0..$#F if $.==1;
print join "\t", 100+(0.33*$i++), @F' ip.txt
20 20.33 20.66 20.99 21.32 21.65
100 2 3 4 1 2 3
100.33 3 4 5 2 4 6
100.66 2 4 0 5 0 7
100.99 0 0 5 6 3 8
-a
到 auto-split 输入空格,结果保存在@F
数组中- 有关命令行选项的详细信息,请参阅 https://perldoc.perl.org/perlrun.html#Command-Switches
if $.==1
为第一行输入map {20.00+$_*0.33} 0..$#F
根据@F
数组的大小进行迭代,对于每次迭代,我们根据{}
中的等式得到一个值,其中$_
将是 [= 20=、1
等直到@F
数组的最后一个索引print join "\t", "", map...
使用制表符分隔符打印空元素和地图结果
- 对于所有行,打印
@F
数组 pre-fixed 的内容以及100+(0.33*$i++)
的结果,其中$i
在数字上下文中最初将是0
。同样,制表符在连接这些值时用作分隔符
如果需要格式化使用sprintf
,也可以初始化$,
而不是使用join
perl -lane 'BEGIN{$,="\t"; $st=0.33}
print "", map { sprintf "%.2f", 20+$_*$st} 0..$#F if $.==1;
print sprintf("%.2f", 100+($st*$i++)), @F' ip.txt
关注 awk
也可能对您有所帮助。
awk -v col=100 -v row=20 'FNR==1{printf OFS;for(i=1;i<=NF;i++){printf row OFS;row=row+.33;};print ""} {col+=.33;=;print col OFS [=10=]}' OFS="\t" Input_file
现在也添加上述解决方案的非一种线性形式:
awk -v col=100 -v row=20 '
FNR==1{
printf OFS;
for(i=1;i<=NF;i++){
printf row OFS;
row=row+.33;
};
print ""
}
{
col+=.33;
=;
print col OFS [=11=]
}
' OFS="\t" Input_file
Awk
解法:
awk 'NR == 1{
long = 20.00; lat = 100.00; printf "%12s%.2f", "", long;
for (i=1; i<NF; i++) { long += 0.33; printf "\t%.2f", long } print "" }
NR > 1{ lat += 0.33 }
{
printf "%.2f%6s", lat, "";
for (i=1; i<=NF; i++) printf "\t%d", $i; print ""
}' file
$ cat tst.awk
BEGIN {
lat = 100
lon = 20
latWid = lonWid = 6
latDel = lonDel = 0.33
latFmt = lonFmt = "%*.2f"
}
NR==1 {
printf "%*s", latWid, ""
for (i=1; i<=NF; i++) {
printf lonFmt, lonWid, lon
lon += lonDel
}
print ""
}
{
printf latFmt, latWid, lat
lat += latDel
for (i=1; i<=NF; i++) {
printf "%*s", lonWid, $i
}
print ""
}
$ awk -f tst.awk file
20.00 20.33 20.66 20.99 21.32 21.65
100.00 2 3 4 1 2 3
100.33 3 4 5 2 4 6
100.66 2 4 0 5 0 7
100.99 0 0 5 6 3 8