Awk 如何从一个文件中grep数据,执行小操作,然后将它们附加到另一个文件中
我有两个文件 一个是(案例1):Awk 如何从一个文件中grep数据,执行小操作,然后将它们附加到另一个文件中,awk,sed,grep,Awk,Sed,Grep,我有两个文件 一个是(案例1): Automatically generated mesh 10 Reciprocal lattice 0.00000000000000 0.00000000000000 0.00000000000000 1 0.20000000000000 -0.00000000000000 -0.00000000000000 8 0.40000000000000 -0.
Automatically generated mesh
10
Reciprocal lattice
0.00000000000000 0.00000000000000 0.00000000000000 1
0.20000000000000 -0.00000000000000 -0.00000000000000 8
0.40000000000000 -0.00000000000000 -0.00000000000000 8
0.20000000000000 0.20000000000000 -0.00000000000000 6
0.40000000000000 0.20000000000000 -0.00000000000000 24
-0.40000000000000 0.20000000000000 0.00000000000000 24
-0.20000000000000 0.20000000000000 0.00000000000000 12
0.40000000000000 0.40000000000000 -0.00000000000000 6
-0.40000000000000 0.40000000000000 0.00000000000000 12
-0.40000000000000 0.40000000000000 0.20000000000000 24
另一个是(案例2)
我需要
k点和权重之间的数据:生成的k路径。
和它之后的第一个空行(即在分数坐标(直接晶格)中具有离子位置的行之前)
case2文件并将最后一列设置为0
倒数格
之后,计算案例1文件中的总行数,以及在步骤1中显示的文件中的总行数,然后
使用案例1第二行中的可用编号更新此编号
文件(此处为10,但可能有所不同)Automatically generated mesh
27
Reciprocal lattice
0.00000000000000 0.00000000000000 0.00000000000000 1
0.20000000000000 -0.00000000000000 -0.00000000000000 8
0.40000000000000 -0.00000000000000 -0.00000000000000 8
0.20000000000000 0.20000000000000 -0.00000000000000 6
0.40000000000000 0.20000000000000 -0.00000000000000 24
-0.40000000000000 0.20000000000000 0.00000000000000 24
-0.20000000000000 0.20000000000000 0.00000000000000 12
0.40000000000000 0.40000000000000 -0.00000000000000 6
-0.40000000000000 0.40000000000000 0.00000000000000 12
-0.40000000000000 0.40000000000000 0.20000000000000 24
0.00000000 0.00000000 0.00000000 0
0.05555556 0.00000000 0.05555556 0
0.11111111 0.00000000 0.11111111 0
0.16666667 0.00000000 0.16666667 0
0.22222222 0.00000000 0.22222222 0
0.27777778 0.00000000 0.27777778 0
0.33333333 0.00000000 0.33333333 0
0.38888889 0.00000000 0.38888889 0
0.44444444 0.00000000 0.44444444 0
0.50000000 0.00000000 0.50000000 0
0.50000000 0.00000000 0.50000000 0
0.51388889 0.02777778 0.51388889 0
0.52777778 0.05555556 0.52777778 0
0.54166667 0.08333333 0.54166667 0
0.55555556 0.11111111 0.55555556 0
0.50000000 0.02777778 0.52777778 0
0.50000000 0.00000000 0.50000000 0
使用GNU awk:
awk 'FNR==NR && /^Reciprocal lattice/ { scnt=1;next } FNR==NR && scnt==1 { cnt++;map1[FNR]=$0 } NR != FNR && /^$/ { scnt1=0 } FNR != NR && / k-points in reciprocal lattice and weights: K-Path Generated./ { scnt1=1;next } FNR != NR && scnt1==1 { cnt++;gsub($4,"0",$4);map[FNR]=$0 } END { PROCINFO["sorted_in"]="@ind_num_asc";print "Automatically generated mesh";printf "\t%s\n",cnt;print "Reciprical lattice";for (i in map1) { print map1[i] } for (i in map) { print map[i] } }' case1 case2
说明:
awk 'FNR==NR && /^Reciprocal lattice/ { # Process the first file (FNR==NR). Where the line start with "Reciprocal lattice" set a marker variable scnt to 1
scnt=1;
next
}
FNR==NR && scnt==1 { # Where it is the first file and marker scnt is 1, process
cnt++; # Increment a total line counter
map1[FNR]=$0 # Set up a map array with the file record number the index and the line ($0) the value
}
NR != FNR && /^$/ { # Process where we encounter the second file (NR != FNR) and the line is blank
scnt1=0 # Set second tracking variable scnt1 to 0
}
FNR != NR && / k-points in reciprocal lattice and weights: K-Path Generated./ {
scnt1=1; # Where it is the second file and we see the text "k-point ...", set second tracking variable scnt1 to 1
next
}
FNR != NR && scnt1==1 { # Process where second file and second tracking variable is 1
cnt++; # Increment total line count
gsub($4,"0",$4); # Use gsub to replace the 4th field with 0
map[FNR]=$0 # Set up another array map with the file number record as the index and the amended line as the value
}
END { # Process at the end of processing both files.
PROCINFO["sorted_in"]="@ind_num_asc"; # Set the array ordering
print "Automatically generated mesh";
printf "\t%s\n",cnt;print "Reciprical lattice"; # Print text and total
for (i in map1) {
print map1[i] # Loop through map1 and print lines
}
for (i in map) {
print map[i] # Loop through map and print lines
}
}' case1 case2
如果您继续添加到我的原始注释中,您可以构建一个简短的
awk
脚本,它将为您处理整个转换过程。你基本上有两套规则。我们将首先读取的case2
文件的规则,您可以比较FNR
(文件记录编号)等于NR
(记录编号),这意味着您正在读取第一个文件
对于要读取的第二个文件,case1
,NR
继续增加,因此当前的FNR
不再等于总的NR
——这是在同一脚本中以不同方式处理每个文件的方便方法
对于case2
和case1
文件,您可以执行以下操作:
awk '
NR==FNR && /k-points/ { c2=1; next }
NR==FNR && !NF { m=c2; c2=0 }
NR==FNR && c2 { sub($NF,"0"); b[c2++] = $0 }
NR!=FNR && /Reciprocal/ { n=1; next }
NR!=FNR && n { a[n++] = $0 }
END {
print "Automatically generated mesh"
print " " m + n - 2
print "Reciprocal lattice"
for (i=1; i<n; i++)
print a[i]
for (i=1; i<m; i++)
print b[i]
}' case2 case1
如果您还有其他问题,请告诉我。好的,您被困在哪里了
awk
可以处理整个事情。我被困在步骤1。用awk'/k-points/{n=1;next}隔离案例2中的记录;NF==0{n=0};n{sub($NF,“0”);print}'case2
确认这是您从case2中需要的内容,然后不打印输出,而是保存到数组并移动到步骤2。(您可以使用数组索引作为计数器)n
只是一个标志,当设置为1
时,它会在的“k点”
行之后收集记录,直到找到一个空行$NF==0
,并且n
被设置回零。它不起作用。谢谢你抽出时间。大卫先生的建议部分奏效了,不用担心。我可以使用GNU awk 4.0.2和您发布的示例验证该解决方案是否有效。啊,我现在知道了。我的集群上没有gnuplot,而且我也无法在其上安装gnu。这就是为什么它对我不起作用的原因。有很多单字母变量名(a,b,m,n,c2)-一些有意义的名称会使代码更容易理解。为什么c2
而不是c
(当然,如果你重命名它,那就无关紧要了)?还可以考虑创建一个单<代码> NR==FNR{…} } /Cuth>块,这样就不必测试<代码> NR==FNR 3次和<代码> NR!FNR两次。@EdMorton-是的,这是非常正确的。我开始使用array1,array2,但后来我测试的一个线性程序变得很长。。。我将来会抵制这种诱惑。:)
awk '
NR==FNR && /k-points/ { c2=1; next }
NR==FNR && !NF { m=c2; c2=0 }
NR==FNR && c2 { sub($NF,"0"); b[c2++] = $0 }
NR!=FNR && /Reciprocal/ { n=1; next }
NR!=FNR && n { a[n++] = $0 }
END {
print "Automatically generated mesh"
print " " m + n - 2
print "Reciprocal lattice"
for (i=1; i<n; i++)
print a[i]
for (i=1; i<m; i++)
print b[i]
}' case2 case1