【问题标题】:format output from Unix "script" command: remove backspaces, linefeeds and deleted chars?Unix“脚本”命令的格式输出:删除退格符、换行符和删除的字符?
【发布时间】:2011-08-22 19:12:05
【问题描述】:

我正在尝试使用script 命令来记录交互式shell 会话,以便我可以使用它来准备文档。

根据手册页:

脚本将所有内容都放在日志文件中,包括换行符和
退格键。这不是天真的用户所期望的。

我是一个天真的用户(通常不会在手册页中大喊大叫,这相当令人兴奋!),我想处理输出,以便删除退格、换行和删除的字符等.

例如,我运行一个 脚本 会话:

stew:~> script -f scriptsession.log
Script started, file is scriptsession.log
stew:~> date
Mon Aug 22 15:00:37 EDT 2011
stew:~> #extra chars: that
stew:~> exit
exit
Script done, file is scriptsession.log

然后我使用 cat 读取会话日志:

stew:~> cat scriptsession.log
Script started on Mon 22 Aug 2011 03:00:35 PM EDT
stew:~> date
Mon Aug 22 15:00:37 EDT 2011
stew:~> #extra chars: that
stew:~> exit
exit

Script done on Mon 22 Aug 2011 03:01:01 PM EDT

但是当我使用 less 时,我看到了使用 cat 不可见的不需要字符的证据:

stew:~> less scriptsession.log
Script started on Mon 22 Aug 2011 03:00:35 PM EDT
stew:~> date
Mon Aug 22 15:00:37 EDT 2011
stew:~> #extra chars: thiESC[ESC[ESC[ESC[Kthat
stew:~> exit
exit

Script done on Mon 22 Aug 2011 03:01:01 PM EDT
scriptsession.log lines 1-8/8 (END)

当我使用 cat 时,我知道它不会删除不可见的字符,它只是不会像 less 那样明显地表示它们——所以如果我将 cat 输出通过管道传输到一个文件,它仍然有不需要的字符。

我想要的输出格式是 cat 显示 的副本。谢谢!

(抱歉,如果这是重复的,搜索“unix 脚本输出格式”会返回很多关于手头问题的噪音结果!)

【问题讨论】:

  • +1 表示“我是天真的用户”。 :-)

标签: bash unix format


【解决方案1】:

col 命令将执行您要查找的部分但不是全部过滤。 (例如,它似乎无法识别粗体和下划线的控制序列。)

我过去使用的一种方法是 (a) 更改我的 shell 提示符,使其不进行任何突出显示(通常会这样做),和/或 (b) 将 $TERM 设置为 "dumb" 所以各种命令不会尝试使用某些控制序列。

【讨论】:

    【解决方案2】:

    我通过在屏幕上运行scriptreplay 并将回滚缓冲区转储到文件中解决了这个问题。

    下面的 expect 脚本会为你做这件事。

    它已针对最多 250.000 行的日志文件进行了测试。在工作目录中,您需要您的脚本日志、一个名为“time”的文件,其中包含 10.000.000 倍的行“1 10”,以及脚本。我需要你的脚本文件名作为命令行参数,比如./name_of_script name_of_scriptlog

    #!/usr/bin/expect -f 
    
    set logfile [lindex $argv 0]
    
    if {$logfile == ""} {puts "Usage: ./script_to_readable.exp \$logfile."; exit}
    
    set timestamp [clock format [clock sec] -format %Y-%m-%d,%H:%M:%S]
    set pwd [exec pwd]
    if {! [file exists ${pwd}/time]} {puts "ERROR: time file not found.\nYou need a file named time with 10.000.000 times the line \"1 10\" in the working directory for this script to work. Please provide it."; exit}
    set wc [exec cat ${pwd}/$logfile | wc -l]
    set height [ expr "$wc" + "100" ]
    system cp $logfile ${logfile}.tmp
    system echo $timestamp >> ${logfile}.tmp
    set timeout -1
    spawn screen -h $height -S $timestamp 
    send "scriptreplay -t time -s ${logfile}.tmp 100000 2>/dev/null\r"
    expect ${timestamp} 
    send "\x01:hardcopy -h readablelog.${timestamp}\r"
    
    send "exit\r"
    
    system sed '/^$/d' readablelog.$timestamp >> readablelog2.$timestamp
    system head -n-2 readablelog2.$timestamp >> ${logfile}.readable.$timestamp
    system rm -f readablelog.$timestamp readablelog2.$timestamp ${logfile}.tmp
    

    时间文件可以通过

    for i in $(seq 1 10000000); do echo "1 10" >> time; done
    

    【讨论】:

      【解决方案3】:

      正如 Keith 所说,col 完成了部分工作(控制字符)。

      您可以进一步使用 ansifilter 删除任何您不想要的 ANSI 转义序列:http://www.andre-simon.de/zip/download.html#ansifilter

      【讨论】:

        【解决方案4】:

        或者您可以使用“更多”命令,该命令将解释这些字符并准确显示您输入的内容、接收到的输出等,就像您在缓冲区中向后滚动一样。

        【讨论】:

        • 绝对不行:\r^H 留在数据中。
        【解决方案5】:
        # awk script
        {
            gsub(/\033\[[CK]/, "")
            while (sub(/.\b/, "")) ;
            print
        }
        

        脚本会删除交错的“ESC [ C”和“ESC [ K”子字符串。 然后将 'c BS' 子串替换为 nothig,其中 c 代表任何字符。

        【讨论】:

        • 你能解释一下这个脚本在做什么吗?
        • 欢迎来到 Stack Overflow!请不要只用源代码回答。尝试对您的解决方案如何工作提供一个很好的描述。请参阅:How do I write a good answer?。谢谢
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-12
        • 2016-02-26
        • 1970-01-01
        相关资源
        最近更新 更多