Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
AWK在文件末尾打印NA的空行_Awk - Fatal编程技术网

AWK在文件末尾打印NA的空行

AWK在文件末尾打印NA的空行,awk,Awk,我有一个老脚本,已经困扰了我一段时间了,其中有一个小错误,我还没有真正花时间去修复,但我认为是时候了。脚本基本上根据行的ID追加不同文件的列。例如 test1.txt: a 3 b 2 test2.txt: a 5 b 9 。。。应产生以下结果: a 3 5 b 2 9 脚本本身如下所示: #!/bin/bash gawk 'BEGIN { OFS="\t" } { vals[$1,ARGIND]=$2; keys[$1] } END {

我有一个老脚本,已经困扰了我一段时间了,其中有一个小错误,我还没有真正花时间去修复,但我认为是时候了。脚本基本上根据行的ID追加不同文件的列。例如

test1.txt:

a   3
b   2
test2.txt:

a   5
b   9
。。。应产生以下结果:

a   3   5
b   2   9
脚本本身如下所示:

#!/bin/bash
gawk 'BEGIN { OFS="\t" } 
    { vals[$1,ARGIND]=$2; keys[$1] } 
    END {
            for (key in keys) {
                printf "%s%s", key, OFS
                for (colNr=1; colNr<=ARGIND; colNr++) {
                    printf "%s%s", vals[key,colNr], (colNr<ARGIND?OFS:ORS)
            }
            } printf "\n"
    }' $1 $2
。。。i、 e.我在文件的最后与NA发生了一行。到目前为止,我只是手动删除了这一行,但最好不用这样做。我真的不知道这个奇怪的功能是从哪里来的,虽然。。。有人有什么想法吗?如果有必要的话,我正在OSX上使用GAWK

这里有一些实际的输入,这就是我试图使问题简单和中肯的结果=P

target_id       length  eff_length  est_counts  tpm
ENST00000574176 596     282         6           0.825408
ENST00000575242 103     718         105         5.19804
ENST00000573052 291     291         21          2.61356
ENST00000312051 223     192         2559        46.8843
我对target_id和tpm列感兴趣,其他的都不重要。我的完整脚本:

FILES=$(find . -name 'data.txt' | xargs)

# Get replicate names for column header
printf "%s" 'ENSTID'
for file in $FILES; do
    file2="${file/.results\/data.txt/}"
    file3="${file2/.\/*\//}"
    printf "\t%s" $file3
done
printf "\n"

gawk 'BEGIN { OFS="\t" } 
    { vals[$1,ARGIND]=$5; keys[$1] } 
    END {
            for (key in keys) {
                printf "%s%s", key, OFS
                for (colNr=1; colNr<=ARGIND; colNr++) {
                    printf "%s%s", vals[key,colNr], (colNr<ARGIND?OFS:ORS)
            }
            } printf "\n"
    }' $FILES

i、 e.所有文件都命名为data.txt,但位于不同名称的子文件夹中。

更简单的惯用方法是

$ cat test1.txt
a   3
b   2
$ cat test2.txt 
a   5
b   9
$ awk -v OFS="\t" 'NR==FNR{rec[$1]=$0;next}$1 in rec{print rec[$1],$2}' test1.txt test2.txt
a   3   5
b   2   9
对于实际输入

注:

-v OFS=\t用于输出中以制表符分隔的字段,传递文件的顺序对第一个解决方案很重要。 硬编码换行符,如中所示

printf "%-20s %-15s %-15s\n", rec1[$1],rec2[$1],$5
这不是一个好主意,因为它会降低脚本的可移植性。您可以用

printf "%-20s %-15s %-15s", rec1[$1],rec2[$1],$5;print # same effect
编辑:用于两个以上的文件


更简单的惯用方法是

$ cat test1.txt
a   3
b   2
$ cat test2.txt 
a   5
b   9
$ awk -v OFS="\t" 'NR==FNR{rec[$1]=$0;next}$1 in rec{print rec[$1],$2}' test1.txt test2.txt
a   3   5
b   2   9
对于实际输入

注:

-v OFS=\t用于输出中以制表符分隔的字段,传递文件的顺序对第一个解决方案很重要。 硬编码换行符,如中所示

printf "%-20s %-15s %-15s\n", rec1[$1],rec2[$1],$5
这不是一个好主意,因为它会降低脚本的可移植性。您可以用

printf "%-20s %-15s %-15s", rec1[$1],rec2[$1],$5;print # same effect
编辑:用于两个以上的文件


就我所见,在输出的末尾出现一个空行的唯一原因是在脚本的末尾有一个printf\n,即使您刚刚打印了ORS,它也会添加一个新行,这也是我在OS X上使用gawk得到的

因为您的bash脚本本质上是一个awk脚本,所以我会用它制作一个合适的awk脚本。这还可以避免在shell脚本中错误地引用$1和$2会破坏外来文件名的问题。如果您最喜欢的文本编辑器理解Awk,这也会为您提供适当的语法高亮显示:

#!/usr/bin/gawk -f

BEGIN { OFS = "\t" }

{
    vals[$1,ARGIND] = $2;
    keys[$1] = 1;
}

END {
    for (key in keys) {
        printf("%s%s", key, OFS);

        for (colNr = 1; colNr <= ARGIND; colNr++) {
            printf("%s%s", vals[key,colNr], (colNr < ARGIND ? OFS : ORS));
        }
    }
}

对于更复杂的sed编辑脚本也可以这样做。

据我所知,在输出末尾出现空行的唯一原因是在脚本末尾有一个printf\n,即使您刚刚打印了ORS,它也会添加一个新行

因为您的bash脚本本质上是一个awk脚本,所以我会用它制作一个合适的awk脚本。这还可以避免在shell脚本中错误地引用$1和$2会破坏外来文件名的问题。如果您最喜欢的文本编辑器理解Awk,这也会为您提供适当的语法高亮显示:

#!/usr/bin/gawk -f

BEGIN { OFS = "\t" }

{
    vals[$1,ARGIND] = $2;
    keys[$1] = 1;
}

END {
    for (key in keys) {
        printf("%s%s", key, OFS);

        for (colNr = 1; colNr <= ARGIND; colNr++) {
            printf("%s%s", vals[key,colNr], (colNr < ARGIND ? OFS : ORS));
        }
    }
}

更复杂的sed编辑脚本也可以这样做。

NA字符串是否在实际输出中?使用…|尾部我只是在结尾处得到一个空行,如果我在文本编辑器/Excel/Textedit中查看文件,NAs就会出现。如果我删除结尾处的printf,我在那里什么也得不到。输出在两行之后停止。这可能是Excel读取空行的结果?哦,这似乎确实有效!谢谢^^将你上面的内容与我给你的脚本进行比较。看到区别了吗?由于某种原因,您在末尾添加了printf\n。顺便说一句,您使用find的方式很脆弱-您应该使用数组而不是变量来存储文件名。NA字符串是否在实际输出中?使用…|尾部我只是在结尾处得到一个空行,如果我在文本编辑器/Excel/Textedit中查看文件,NAs就会出现。如果我删除结尾处的printf,我在那里什么也得不到。输出在两行之后停止。这可能是Excel读取空行的结果?哦,这似乎确实有效!谢谢^^将你上面的内容与我给你的脚本进行比较。看到区别了吗?由于某种原因,您在末尾添加了printf\n。顺便说一句,您使用find的方式是脆弱的——您应该使用数组而不是变量来存储文件名++@sjsam是的,但我弄错了:-需要有-f,所以不能使用env。嗯,我必须用printf检查一下\n。。。但是,我使用bash的原因是,该脚本有一个稍大的脚本的一部分,该脚本可以在不同的子文件夹中找到任意数量的同名文件,因此我不能使其成为awk,只是我担心。@Sajber从bash中调用单独的awk脚本没有什么错。嗯,这甚至会使shell脚本更干净。与shebang的接触很好,这是一个经常被忽略的事实++@sjsam是的,但我弄错了:-需要有-f,所以不能使用env。嗯,我必须用printf检查一下\n。。。然而,我使用bash的原因是scri
pt有一个稍大一点的脚本的一部分,该脚本在不同的子文件夹中找到任意数量的同名文件,因此我恐怕只能将其设置为awk。@Sajber从bash中调用单独的awk脚本没有什么错。这甚至会使shell脚本更干净。对于示例文件来说效果很好,但我意识到它们可能太简单了。。。我只需要我的真实数据文件中的第一个ID和第五个值列,而你的版本似乎与之不符。@Sajber:介意在问题中发布一些实际的输入和输出吗;我只需要真实数据文件中的第一个ID和第五个值列,对于这两个文件?使用示例数据编辑原始问题所有文件看起来都一样,包含相同的ID第一列,但第五列的值不同。我还需要能够输入任意数量的这些文件,因为这取决于所讨论的实验。@Sajber:我已经为实际的输入文件提供了解决方案。如果足够的话,你可以接受答案。对于示例文件来说效果很好,但我意识到它们可能太简单了。。。我只需要我的真实数据文件中的第一个ID和第五个值列,而你的版本似乎与之不符。@Sajber:介意在问题中发布一些实际的输入和输出吗;我只需要真实数据文件中的第一个ID和第五个值列,对于这两个文件?使用示例数据编辑原始问题所有文件看起来都一样,包含相同的ID第一列,但第五列的值不同。我还需要能够输入任意数量的这些文件,因为这取决于所讨论的实验。@Sajber:我已经为实际的输入文件提供了解决方案。如果足够的话,你可以接受答案。