使用awk对行变量

时间:2011-10-26 23:02:37

标签: variables awk

只是运行一个相当简单的脚本,但是出现了错误,我想可能是使用awk变量的问题。也许我想念一些关于awk的基础课 请看下面的内容:

#!/bin/bash
for((c=1;c<=542;c++))
do
    LINE=`head -$c FM_DEL_50r.bed|tail -1`
        cat $LINE|awk '{print $1" "$2" "$3}'

done

FM_DEL_50r.bed看起来像:

chr1    3392391 3658426 DEL chr1    3392364 3658425 DEL
chr1    4011952 4392064 DEL chr1    4011953 4392062 DEL
chr1    4468526 4665322 DEL chr1    4468523 4665322 DEL
chr1    5759839 5997664 DEL chr1    5759836 5997664 DEL

错误就像:

cat: chr1: No such file or directory
cat: 3392391: No such file or directory
cat: 3658426: No such file or directory
cat: DEL: No such file or directory
cat: chr1: No such file or directory
cat: 3392364: No such file or directory
cat: 3658425: No such file or directory
cat: DEL: No such file or directory

谁能告诉我这是什么问题? THX

3 个答案:

答案 0 :(得分:1)

头部和尾部会给你一条线  一份文件。要输出这样的字符串,请使用“echo”,cat用于将流或文件的内容打印到stdout。这就是您收到错误消息的原因。

无论如何,你想做什么?你想读文件吗? FM_DEL_50r.bed逐行排列并打印出第1,2和3列。 然后尝试:

命令:

awk 'NR<543{print $1 " " $2 " " $3}' x

输出:

chr1 3392391 3658426
chr1 4011952 4392064
chr1 4468526 4665322
chr1 5759839 5997664

答案 1 :(得分:1)

Chris的回答是正确的,但是当您在评论中询问“代码有什么问题”时,代码的问题是cat通常期望文件名作为句子,以及运行{{1}的输出将被转储到屏幕或任何尾随管道的所有文件的完整内容。

如果在循环之前使用shell调试功能cat file1 file2 ...,您将看到$ LINE如何作为文件列表传递给cat。当然,您可以通过消息看到这一点获得

set -vx

要修复代码,请将cat: chr1: No such file or directory cat: 3392391: No such file or directory .... 替换为cat $LINE,以保留文件输出中的空格/制表符OR echo "$LINE",并在LINE上的每个单词之间获取一个空格。

通过从文件中echo $LINE递增$c来打印每一行的解决方案效率极低。您必须完全读取每行数据的文件。虽然这对于小文件可以正常工作,但如果将此技术应用于具有数千行的文件,则执行时间将呈指数级增长(抱歉,不是精确预测),而不是花费不到1秒来处理文件,需要100秒或1,000秒。

(不错的问题,我很欣赏示例数据。它还有助于至少包含一行或两行预期输出。)

我希望这会有所帮助。

答案 2 :(得分:1)

要在bash中正确执行此操作:

count=0
while read a b c rest_of_line; do
  echo $a $b $c
  (( ++count == 542 )) && break
done < FM_DEL_50r.bed

或者

head -542 FM_DEL_50r.bed | while read a b c rest_of_line; do echo $a $b $c; done