gpt4 book ai didi

awk - 如何在每次迭代中从不同的行开始对每第 n 行进行 awk

转载 作者:行者123 更新时间:2023-12-04 21:12:38 24 4
gpt4 key购买 nike

我要 awk从第 0 行开始打印文件中的每第 n 行。然后,在 awk 遍历整个文件后,我希望它从第 1 行开始打印每第 n 行...然后从第 2 行开始打印每第 n 行...等,直到从第 n-1 行开始打印每第 n 行。到目前为止,我悲伤的尝试:

#!/bin/bash

rm *.sad *.sadd *.out

#Create loop index
for i in $(seq 20 1 36);
do
listm+=($i)
done

#Create input file
for j in "${listm[@]}"
do
if [ $j -eq 20 ];
then
awk 'NR % 20 == 0' vel_VMDout > atomvel.dat
awk '{print $2,$3,$4}' atomvel.dat > velocity.dat
else
awk 'NR % 20 == 1' vel_VMDout > $j.sad
egrep -v "^[[:space:]]*$|^#" $j.sad > $j.sadd
awk '{print $2, $3, $4}' $j.sadd > $j.out
paste velocity.dat $j.out > taste
fi
done

让我尝试通过提供输入和输出应该是什么样子来澄清这一点。输入是由原子的 xyz 坐标系组成的 MD 模拟的 xyz 文件。

输入:

input

此图像显示了第一个快照和第二个快照的一部分。因为这些是快照,所以原子的顺序不会改变。因此,我试图从每个快照中为每个特定原子在它们自己的列中打印 xyz 坐标,如下所示。这最终会生成一个由 3N 列组成的文件,其中 N 是原子数。

输出:

output

如您所见,每个原子的坐标都在它们自己的列中,并且整个文件是一个 Nx3N 数组。我的 bash 脚本是我试图这样做,但只能做前两个原子。我想打印每第 n 行(第 n 个原子的坐标),使它们看起来像输出。我真的很感谢你们的耐心。

最佳答案

生成样本数据

这是一个不必要的步骤;该问题应该包括可用的样本数据和该样本数据所需的输出。

一方面,它不会有太大帮助,因为您没有我的随机数生成器程序,但下面的脚本显示了我如何生成随后的数据,并说明了当问题不提供可读数据。我生成了一些看起来与问题中的数据相似的数据(至少从表面上看):

18
Generated by VMD in absentia
C 0.979485 -6.665347 0.575383
C 1.191999 -3.002386 2.859484
C 3.151517 -5.610077 0.429413
C 3.439828 -6.454984 1.319724
C 3.726201 -0.123038 2.096854
C 1.363325 -3.031238 0.016019
C 6.090283 -3.915340 2.396358
C 0.407755 -7.957784 -0.846842
C 0.203074 -0.796428 2.659573
O 2.600610 -2.259674 -0.260378
O 4.773839 -6.765097 0.588508
H 2.743424 -2.890016 2.906452
H 2.810233 -6.641054 -0.797672
H 6.854169 -3.191721 -0.925670
O 2.914233 -1.060001 0.776983
H 3.803923 -1.497032 2.908799
H 5.669443 -7.227666 -0.647552
H 0.092455 -5.850637 2.959987
18
Generated by VMD in absentia
C 6.042840 -7.254720 2.093573
C 2.551942 -6.044322 2.061072
C 3.523150 -6.167163 2.451689
C 5.197316 -3.429866 -0.412062
C 2.548777 -6.422851 1.282846
C 3.775197 -2.012031 1.377440
C 3.405112 -3.206415 -0.879886
C 1.448359 -5.419629 0.467291
C 3.661964 -2.789234 2.644294
O 4.214854 -2.439574 -0.951704
O 5.297609 -2.320418 2.709898
H 2.653940 -4.431080 -0.511743
H 5.040635 -0.676199 -0.590970
H 1.546725 -1.294582 2.562937
O 4.231461 -7.180908 1.629901
H 3.297836 -1.557133 -0.133280
H 3.442481 -4.489962 2.111930
H 1.423611 -7.982655 0.715618
18
Generated by VMD in absentia
C 1.432495 -7.686243 2.525734
C 5.038409 -4.976270 2.826846
C 6.184137 -7.303094 2.711561
C 3.208125 -0.606556 1.978725
C 2.171859 -6.792060 0.678988
C 6.521124 -5.622797 -0.773797
C 1.725619 -5.768633 -0.223397
C 3.602427 -2.325680 1.762008
C 1.937521 -1.686895 1.743159
O 0.745526 -0.114246 -0.949490
O 4.754360 -6.531145 1.998913
H 1.114732 -1.158810 1.486939
H 6.410490 -5.411647 0.062737
H 4.164330 -6.743763 1.802804
O 2.587841 -3.979700 2.609748
H 2.192073 -2.815376 -0.809569
H 5.501795 -2.326438 1.325829
H 3.285032 -1.212541 1.284453
18
Generated by VMD in absentia
C 3.564424 -3.117406 -0.032879
C 2.894745 -0.632591 0.532311
C 3.384916 -5.383135 1.179585
C 0.793488 -0.894539 -0.886891
C 1.348785 -6.501867 1.648604
C 2.189941 -2.438067 0.616090
C 2.043378 -4.966472 0.691603
C 3.124161 -5.792896 0.545362
C 5.741472 -0.640590 2.825374
O 0.300550 -7.149663 0.942726
O 1.344387 -0.121382 2.169401
H 4.963296 -0.964665 -0.230523
H 6.651423 -4.905053 2.509626
H 5.059694 -6.166516 0.102255
O 5.046864 -3.288883 0.853948
H 2.389007 -3.057664 1.806301
H 2.365876 -0.956860 1.458959
H 2.892502 -0.097422 -0.531714

我用来做的脚本是:
random -n $((4 * 18)) -T '%8:6[0:7]F   %8:6[-8:0]F   %8:6[-1:3]F' |
awk 'BEGIN { n = split("CCCCCCCCCOOHHHOHHH", atoms, ""); atoms[0] = atoms[n] }
NR % n == 1 { print n; print " Generated by VMD in absentia" }
{ print "", atoms[NR%18], " ", $0 }'
-n选项 random表示要生成多少行;我选择了 72。 -T option 是一个模板,符号 %8:6[0:7]F表示使用 %8.6F格式以打印 0 到 7 之间均匀分布的随机数。 awk脚本获取如此生成的数据并插入噪声(原子数和“由 VMD 生成”行上的变体),并用适当的原子符号标记这些行。

处理样本数据

给定一些数据,然后您需要对其进行处理以获得所需的输出。这个脚本或多或少地完成了这项工作。当然还有无数的方法需要改进,比如将文件名作为命令行参数,使用临时文件名代替固定名,清理中间文件,不同的化合物,不同的原子(氮、磷等),等等。但是,它应该很容易适应。
input="data"
output="output"
n=$(sed 1q "$input")
n2=$(($n+2))

for ((i = 3; i <= n2; i++))
do
colno=$(printf "%.2d" $(($i-2)))
awk -v N=$n2 -v R=$i \
' BEGIN { name["C"] = "Carbon"; name["H"] = "Hydrogen"; name["O"] = "Oxygen";
R0 = R % N }
NR > 2 && NR <= R { count[$1]++; }
NR == R { printf "%-32.32s\n", name[$1] " " count[$1]; }
NR % N == R0 { xyz = sprintf("%s %s %s", $2, $3, $4); printf "%-32.32s\n", xyz }
' "$input" > "column.$colno"
done

paste -d ' ' column.* > "$output"

前四行设置控制参数,从输入文件中收集每单位数据的行数,并相应地进行调整。 for循环遍历偏移量 3$n2包含(跳过两个标题行),并运行 awk脚本。它对原子类型( BEGIN )进行编码,确定这次它正在处理哪个原子( NR > 2 && NR <= RNR == R ),然后安排打印相关原子的三元组数据。格式经过精心组织,以便列标题和实际的 xyz 三元组间隔均匀。这些被写入文件 column.$colno .完成后, column.*粘贴文件以生成单个输出文件,如下所示:
Carbon 1                         Carbon 2                         Carbon 3                         Carbon 4                         Carbon 5                         Carbon 6                         Carbon 7                         Carbon 8                         Carbon 9                         Oxygen 1                         Oxygen 2                         Hydrogen 1                       Hydrogen 2                       Hydrogen 3                       Oxygen 3                         Hydrogen 4                       Hydrogen 5                       Hydrogen 6                      
0.979485 -6.665347 0.575383 1.191999 -3.002386 2.859484 3.151517 -5.610077 0.429413 3.439828 -6.454984 1.319724 3.726201 -0.123038 2.096854 1.363325 -3.031238 0.016019 6.090283 -3.915340 2.396358 0.407755 -7.957784 -0.846842 0.203074 -0.796428 2.659573 2.600610 -2.259674 -0.260378 4.773839 -6.765097 0.588508 2.743424 -2.890016 2.906452 2.810233 -6.641054 -0.797672 6.854169 -3.191721 -0.925670 2.914233 -1.060001 0.776983 3.803923 -1.497032 2.908799 5.669443 -7.227666 -0.647552 0.092455 -5.850637 2.959987
6.042840 -7.254720 2.093573 2.551942 -6.044322 2.061072 3.523150 -6.167163 2.451689 5.197316 -3.429866 -0.412062 2.548777 -6.422851 1.282846 3.775197 -2.012031 1.377440 3.405112 -3.206415 -0.879886 1.448359 -5.419629 0.467291 3.661964 -2.789234 2.644294 4.214854 -2.439574 -0.951704 5.297609 -2.320418 2.709898 2.653940 -4.431080 -0.511743 5.040635 -0.676199 -0.590970 1.546725 -1.294582 2.562937 4.231461 -7.180908 1.629901 3.297836 -1.557133 -0.133280 3.442481 -4.489962 2.111930 1.423611 -7.982655 0.715618
1.432495 -7.686243 2.525734 5.038409 -4.976270 2.826846 6.184137 -7.303094 2.711561 3.208125 -0.606556 1.978725 2.171859 -6.792060 0.678988 6.521124 -5.622797 -0.773797 1.725619 -5.768633 -0.223397 3.602427 -2.325680 1.762008 1.937521 -1.686895 1.743159 0.745526 -0.114246 -0.949490 4.754360 -6.531145 1.998913 1.114732 -1.158810 1.486939 6.410490 -5.411647 0.062737 4.164330 -6.743763 1.802804 2.587841 -3.979700 2.609748 2.192073 -2.815376 -0.809569 5.501795 -2.326438 1.325829 3.285032 -1.212541 1.284453
3.564424 -3.117406 -0.032879 2.894745 -0.632591 0.532311 3.384916 -5.383135 1.179585 0.793488 -0.894539 -0.886891 1.348785 -6.501867 1.648604 2.189941 -2.438067 0.616090 2.043378 -4.966472 0.691603 3.124161 -5.792896 0.545362 5.741472 -0.640590 2.825374 0.300550 -7.149663 0.942726 1.344387 -0.121382 2.169401 4.963296 -0.964665 -0.230523 6.651423 -4.905053 2.509626 5.059694 -6.166516 0.102255 5.046864 -3.288883 0.853948 2.389007 -3.057664 1.806301 2.365876 -0.956860 1.458959 2.892502 -0.097422 -0.531714

你的任务是理解为什么 awk 的所有位脚本存在。例如,为什么是 R0需要(提示,在没有 R0 计算的情况下进行实验,并在其位置使用 R)。

关于awk - 如何在每次迭代中从不同的行开始对每第 n 行进行 awk,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31353219/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com