给定行范围后,如何使用sed命令从文本文件中提取内容?

时间:2018-10-27 06:38:24

标签: linux bash shell sed

#!/bin/bash

export ORACLE_SID=orcl
export ORACLE_BASE=/u01/app/oracle
export LOG_DIR=$ORACLE_BASE/diag/rdbms/$ORACLE_SID/$ORACLE_SID/trace

LINE_COUNT_OLD=0

while true
do  
    LINE_COUNT=`wc -l $LOG_DIR/alert_orcl.log | awk '{print $1}'`
    DIFF=`expr $LINE_COUNT - $LINE_COUNT_OLD`
    if [ $DIFF -ne 0 ] && [ $LINE_COUNT_OLD -ne 0 ]
    then
        COUNT=0
        COUNT=`tail -$DIFF $LOG_DIR/alert_orcl.log|grep 'ORA-'|wc -l`
        if [ $COUNT -ne 0 ]
        then
            sed -n '$LINE_COUNT_OLD, $LINE_COUNT' $LOG_DIR/alert_orcl.log > $LOG_DIR/alert_orcl_tmp.log
            cat $LOG_DIR/alert_orcl_tmp.log >> $LOG_DIR/alert_orcl_email.log
        fi
    fi
    sleep 10
    LINE_COUNT_OLD=$LINE_COUNT
    rm -f $LOG_DIR/alert_orcl_tmp.log 
done

在上述bash脚本中出现以下错误

sed: -e expression #1, char 3: extra characters after command

所以我对sed -n命令有疑问。但是用下面的数字替换变量,此命令可以正常工作

sed -n '6512, 6671 p' $LOG_DIR/alert_orcl.log

需要帮助来通过sed -n命令传递变量

2 个答案:

答案 0 :(得分:2)

您的sed命令出现了主要问题,因为您在中用了单引号变量:

sed -n '$LINE_COUNT_OLD, $LINE_COUNT' ...

当您使用单引号变量时,会阻止外壳程序 variable扩展,因此sed的字面含义是:

sed -n '$LINE_COUNT_OLD, $LINE_COUNT' ...

尝试从字符$LINE_COUNT_OLD, $LINE_COUNT解析文字范围'$' 'L' 'I' 'N' 'E' '_' 'C' 'O' 'U' 'N' 'T' '_' 'O' 'L' 'D', ...

要解决此问题,请对变量使用双引号

sed -n "$LINE_COUNT_OLD, $LINE_COUNT" ...

接下来,您需要更新一些小事项。首先,避免使用expr $LINE_COUNT - $LINE_COUNT_OLD,这是一种过时的(缓慢的)算术方法。而是使用算术运算符$((LINE_COUNT - LINE_COUNT_OLD))注意: $不需要在$((..))中引用变量)

接下来,除非您知道不引用的确切原因,否则应对bash中的所有变量进行双引号,以防止分词。特别是在[...]中。否则,如果您的变量中有空格,则会向test传递错误数量的参数。同样,用[...]引用诸如-ne '0'之类的非变量也是一个好主意(在这里,单引号可以)。

最后,避免使用ALLCAPS变量名。这些通常保留给外壳使用。

答案 1 :(得分:1)

使用双引号字符串传递必需的参数,以便外壳程序可以对其进行评估。

sed -n "$varA, $varB" $LOG_DIR/alert_orcl.log