我正在尝试将awk BEGIN代码变成一个循环。原始代码用于基于“批处理”(Batch)列的值编辑数据并输出文件。
这是原始代码(效果很好):
awk '
BEGIN{
FS=OFS=","
}
FNR==1{
for(i=1;i<=NF;i++){
if($i=="YBr"){
field=i
}
if($i=="NationalCowID"){
value=i
}
}
}
$field==1{
for(i=value+1;i<=NF;i++){
$i="*"
}
}
1
' obvs.csv > obvs1.csv
上面的代码采用如下所示的文件obvs.csv:
NationalCowID,TestDate,Batch,LN,DIM,YBr,year,CH4,PLS,qtl
206004574,20141208,6,2,92,1,2014,424.4410055,NA,1
206004573,20141209,6,2,93,2,2014,436.4504712,NA,4
206004575,20141207,6,2,91,1,2014,380.94688,NA,6
206004576,20141208,6,2,92,2,2014,424.4410055,NA,7
206004579,20141209,6,2,93,2,2014,436.4504712,NA,8
206004571,20141207,6,2,91,1,2014,380.94688,NA,9
并编辑数据,使其看起来像这样(obvs1.csv):
NationalCowID,TestDate,Batch,LN,DIM,YBr,year,CH4,PLS,qtl
206004574,*,*,*,*,*,*,*,*,*,1
206004573,20141209,6,2,93,2,2014,436.4504712,NA,4
206004575,*,*,*,*,*,*,*,*,*,6
206004576,20141208,6,2,92,2,2014,424.4410055,NA,7
206004579,20141209,6,2,93,2,2014,436.4504712,NA,8
206004571,*,*,*,*,*,*,*,*,*,9
我想将此代码转换为循环,以便创建一个新文件,并开始将编辑应用于“ Batch”列(1-6)的每个值。我已经阅读了一些示例和命令说明,但我不完全了解代码各部分的功能。 例如,与已经编码的$ i相比,我如何编码$ j? 这是我尝试创建的循环:
for j in {1..6}
do
awk '
BEGIN{
FS=OFS=","
}
FNR==$j{
for(i=1;i<=NF;i++){
if($i=="Batch"){
field=i
}
if($i=="NationalCowID"){
value=i
}
}
}
$field==1{
for(i=value+1;i<=NF;i++){
$i="*"
}
}
$j
' obvs.csv > obvs$j.csv
done
最后,我希望有6个文件,如下所示:
obvs1.csv -> only lines with batch = 1 are edited
obvs2.csv -> only lines with batch = 2 are edited
obvs3.csv-> only lines with batch = 3 are edited
obvs4.csv-> only lines with batch = 4 are edited
obvs5.csv-> only lines with batch = 5 are edited
obvs6.csv-> only lines with batch = 6 are edited
因此,文件名与“批处理”相对应,该“批处理”用作指示要编辑哪一行的指示器。也就是说,对于obvs2.csv,对于数据行(批处理等于2),除了第一个和最后一个列之外的所有列都将被编辑为*。 到目前为止,我最终得到了6个正确命名的文件,但是文件中的编辑不正确。 任何方向/代码解释都将不胜感激!
答案 0 :(得分:1)
请您尝试一次。
import numpy as np
def shuffle(data,data_size):
for step in range(int(1*data_size)):
selected = int(np.random.uniform(0,data_size))
target = int(np.random.uniform(0,data_size))
print(data)
if selected!=target:
data[[selected, target]] = data[[target, selected]]
print(selected," and ",target, " are changed")
return data
data = [[[1,2,3,4],[1,2,3,5],[1,2,3,6]],
[[2,2,3,4],[2,2,3,5],[2,2,3,6]],
[[3,2,3,4],[3,2,3,5],[3,2,3,6]] ]
data = np.array(data)
data = shuffle(data,3)
上面的代码将创建2个名为awk '
BEGIN{
FS=OFS=","
}
FNR==1{
head=$0
next
}
{
count[$6]
a[++val]=$0
}
END{
for(i in count){
for(j=1;j<=val;j++){
num=split(a[j],array,",")
if(!header["output_file"i]++){
print (head) > "output_file"i
}
if(array[6]==i){
for(k=2;k<=(num-1);k++){
value=value?value OFS "*":"*"
}
}
if(value){
print (array[1],value,array[num]) > "output_file"i
}
else {print (a[j]) > "output_file"i}
value=""
}
}
}' Input_file
和output_file1
的输出文件,您也可以根据需要更改输出文件名。
输出文件的值如下。
output_file2
很快就会添加解释。
编辑: 。现在在代码上方也添加了说明。
cat output_file1
NationalCowID,TestDate,Batch,LN,DIM,YBr,year,CH4,PLS,qtl
206004574,*,*,*,*,*,*,*,*,1
206004573,20141209,6,2,93,2,2014,436.4504712,NA,4
206004575,*,*,*,*,*,*,*,*,6
206004576,20141208,6,2,92,2,2014,424.4410055,NA,7
206004579,20141209,6,2,93,2,2014,436.4504712,NA,8
206004571,*,*,*,*,*,*,*,*,9
cat output_file2
NationalCowID,TestDate,Batch,LN,DIM,YBr,year,CH4,PLS,qtl
206004574,20141208,6,2,92,1,2014,424.4410055,NA,1
206004573,*,*,*,*,*,*,*,*,4
206004575,20141207,6,2,91,1,2014,380.94688,NA,6
206004576,*,*,*,*,*,*,*,*,7
206004579,*,*,*,*,*,*,*,*,8
206004571,20141207,6,2,91,1,2014,380.94688,NA,9
答案 1 :(得分:0)
问题在于您正在混合bash变量和awk变量。因此,建议重复。您提供的awk
代码也无法执行您提到的替换。
这是原始代码的外观:
BEGIN{FS=OFS=","}
(FNR==1) {
for (i=1;i<=NF;++i) {
if ($i == "YBr") bfield=i;
else if ($i == "NationalCowID") cfield=i
}
}
($bfield == 1) { for(i=cfield+1;i<NF;++i) $i="*" }
1
您现在可以调整以包含$bfield
应该具有的值:
awk -v bvalue="$j" '
BEGIN{FS=OFS=","}
(FNR==1) {
for (i=1;i<=NF;++i) {
if ($i == "Batch") bfield=i;
else if ($i == "NationalCowID") cfield=i
}
}
($bfield == bvalue) { for(i=cfield+1;i<NF;++i) $i="*" }
1
' file.csv