从sed和awk打印详细进度

从sed和awk打印详细进度,sed,awk,Sed,Awk,程序sed和awk通常安静地工作。有没有办法让这些程序说明它们在做什么?如果您将sed或awk的输出重定向到一个文件(而不是就地修改文件),您可以给pv(“管道查看器”)一个镜头: 您可以使用pv-l使其以书面形式报告进度。进度状态被打印到stderr,而实际数据从stdin到stdout,您可以随时告诉awk打印输入记录,即 awk '{ print "#dbg:$0="$0 # do more stuff print $1 # o

程序
sed
awk
通常安静地工作。有没有办法让这些程序说明它们在做什么?

如果您将
sed
awk
的输出重定向到一个文件(而不是就地修改文件),您可以给
pv
(“管道查看器”)一个镜头:


您可以使用
pv-l
使其以书面形式报告进度。进度状态被打印到
stderr
,而实际数据从
stdin
stdout
,您可以随时告诉awk打印输入记录,即

 awk '{ 
       print "#dbg:$0="$0 
       # do more stuff
       print $1
       # or make it conditional
       if ($0 ~ /specialRegEx/){
              print "#dbg:$0="$0 
       }
      }' infile
使用sed时,可以使用'p'cmd打印每一行,不过默认情况下是打印每一行。差不多

 sed 'p
      # also "=" prints line # being processed
      =
      /specialRegEx/{
        s/xxx/yyy/
        p
      }' infile
我希望这有帮助。

这可能对您(sed)有用:


这将在应用更改后打印文件的内容。

如果您在Linux上,您可以通过查看
/proc//fdinfo
查看处理大型文件的进程进度。每个打开的文件描述符都有一个条目,如果您对这些条目进行cat,它们将显示文件描述符的读/写位置。因此,您可以看到文件中有
1123456
字节。打开文件的路径名位于另一个区域:
/proc//fd
,表示为符号链接


在我查看它之前,我通常会在进程中附加一个
strace
strace-p
。您可以使用它来观察进程正在进行的系统调用:文件读取和写入,以及使用
brk
mmap
的内存分配。假设您正在将sed输出传输到文件,您可以使用tail命令(在另一个终端中)不断查看文件的结尾;这样你就能看到进展了

tail -f output_from_sed.txt

这可能不是你想要的,但它可能会帮助其他人。 FWIW:
gawk-W dump variables=/tmp/awk.log


将脚本末尾的变量值转储到日志文件。

这是基于Poton的答案。以下代码将“ll”替换为“zz”,创建备份文件,显示新文本,并将更改写入文件

$ echo hello > test
$ sed -e 's/ll/zz/;w /dev/stdout' -i .backup test
hezzo
$ cat test
hezzo
$ cat test.backup 
hello
这里的“正确”答案是

pv myfile.txt | sed ...
Eduardo Ivanec的答案很接近,但通过使用管道查看器(pv)进行实际管道,您可以了解文件中的进度(以百分比表示,包括M/sec、总数据等重要统计数据)

pv
的工作原理类似于
cat
(读取文件并将其直接导出到
stdout
,或者在管道中,它是
stdin
stdout
之间的桥梁)

重要的是,由于
pv
是一个“透明的管道过程”,因此标准输出被中继数据占用。因此,进度报告通过
stderr

awk
输出到
/dev/stderr
我有时处理涉及4行块的大型数据文件(FASTQ),因此我经常使用
stderr
定期(每100K行)输出状态消息。以下是一个基本模板:

#!/usr/bin/awk -f

BEGIN {
    # Check for any expected input variables

    # Status
    print "[INFO] Initiating processing..." > "/dev/stderr";
}
{
    # Do stuff

    # Status
    if (NR % 400000 == 0) {
        printf("[INFO] %d reads processed\n", NR/4) > "/dev/stderr";
    }
}
END {
    # Final status
    printf("[INFO] %d total reads\n", NR/4) > "/dev/stderr";
}

对我来说,原始命令中的-i在OS X上不起作用。是否缺少-e?Paul的评论:使用sed For OS X的工作示例:
$echo hello>test$sed-e的s/ll/zz/;w/dev/stdout'-i.backup test hezzo$cat test hezzo$cat test.backup hello
Paul:Mac OS X使用的是sed的BSD版本,它在某些方面与Linux系统上常见的GNU版本有所不同。对于BSD sed,您必须始终为-i指定一些扩展名,而GNU sed不将任何内容解释为空字符串。因此,与GNU sed的
sed-i
等效的BSD sed就是
sed-i'
。StuartLC的示例在两个版本上都是一样的,因为他没有在适当的位置编辑文件(即,他使用的是非零长度扩展名,因此不会遇到这种小差异)。在较新的sed版本中,如果省略了w前面的分号,w将成为“s”sed命令的参数,并且只有更改才会写入/dev/stdout,对我来说,这比编写整个文件更有用2020:g必须为全局替换添加->sed-i的/oldtext/newtext/gw/dev/stdout'注意,这不适用于就地替换。。。(AFAIK)为方便起见:
ps ax | grep foo
其中
foo
是相关程序的名称,可用于查找上面使用的进程id。
pv myfile.txt | sed ...
#!/usr/bin/awk -f

BEGIN {
    # Check for any expected input variables

    # Status
    print "[INFO] Initiating processing..." > "/dev/stderr";
}
{
    # Do stuff

    # Status
    if (NR % 400000 == 0) {
        printf("[INFO] %d reads processed\n", NR/4) > "/dev/stderr";
    }
}
END {
    # Final status
    printf("[INFO] %d total reads\n", NR/4) > "/dev/stderr";
}