【发布时间】:2012-04-07 16:52:23
【问题描述】:
程序sed 和awk 通常会安静地工作。有什么方法可以让这些程序说明它们在做什么?
【问题讨论】:
程序sed 和awk 通常会安静地工作。有什么方法可以让这些程序说明它们在做什么?
【问题讨论】:
这是基于波东的回答。以下代码将“ll”替换为“zz”,创建备份文件,显示新文本,并将更改写入文件。
$ echo hello > test
$ sed -e 's/ll/zz/;w /dev/stdout' -i .backup test
hezzo
$ cat test
hezzo
$ cat test.backup
hello
【讨论】:
假设您将 sed 输出通过管道传输到文件,您可以使用 tail 命令(在另一个终端中)不断查看文件末尾;这样您就可以看到进度。
tail -f output_from_sed.txt
【讨论】:
这可能对你有用(对于 sed):
sed -i 's/foo/bar/;w /dev/stdout' files*
这将在应用更改后打印文件的内容。
【讨论】:
$ echo hello > test $ sed -e 's/ll/zz/;w /dev/stdout' -i .backup test hezzo $ cat test hezzo $ cat test.backup hello
sed -i 等效的 BSD sed 就是 sed -i ''。 StuartLC 的示例在任一版本上的工作方式都相同,因为他没有在适当的位置编辑文件(即,他使用的是非零长度扩展名,因此不会遇到这个小差异)。
您总是可以告诉 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 或awk 的输出重定向到文件(而不是就地修改文件),您可以试一试pv(“管道查看器”):
sed -e '...' input.txt | pv > output.txt
您可以使用pv -l 使其以书面形式报告进度。进度状态打印到stderr,而实际数据从stdin 到stdout。
【讨论】:
如果您使用的是 Linux,您可以通过查看 /proc/<pid>/fdinfo 查看处理大文件的进程的进度。每个打开的文件描述符都有一个条目,如果您对条目进行分类,它们会向您显示文件描述符的读/写位置。所以你可以看到你在文件中是1123456字节。打开文件的路径名在另一个区域:/proc/<pid>/fd,表示为符号链接。
在查看之前,我通常会在进程中附加一个strace:strace -p <pid>。您可以使用它来查看进程正在执行的系统调用:文件读取和写入,以及brk 或mmap 的内存分配。
【讨论】:
ps ax | grep foo 其中foo 是有问题的程序的名称,可用于查找上面使用的进程ID。
这可能不是您正在寻找的,但它可能对其他人有所帮助。
FWIW:gawk -W dump-variables=/tmp/awk.log
将脚本末尾的变量值转储到日志文件中。
【讨论】:
这里的“正确”答案是
pv myfile.txt | sed ...
Eduardo Ivanec 的回答很接近,但是通过使用管道查看器 (pv) 进行实际管道,您可以了解文件中的进度(以百分比表示,包括 M/sec 等重要统计数据、总数据等)。
pv 与cat 一样工作(读取文件并将其直接导出到stdout,或者在管道输入的情况下,它是stdin 和stdout 之间的桥梁。
重要的是,由于pv 是一个“透明管道进程”,stdout 被用于中继数据。所以进度报告是通过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";
}
【讨论】: