Shell脚本在排除多个模式后查找并替换字符串模式

时间:2018-08-24 09:13:59

标签: bash shell sed grep

我需要更改以下详细信息:

  1. 搜索每个shell文件,每行包含“ echo”或“ echo -e”(在echo之前或之后可能有空格)替换为“ logger”,其中包含重定向到另一个文件的
  2. 如果一行仅包含“ echo”,则也必须替换为“ logger”
  3. 将“ \ n”或“ \ t”替换为每行中的空白
  4. 找到“ 2>&1”,然后删除直到行尾

但是不应更改在其他地方存在的“ echo”。其他地方意味着:

  1. 在sqlplus内部设置回显或

  2. 回显变量以剪切或分配给另一个变量等。

示例文件:run.sh

1   echo "**********************"   2>&1 | tee -a  out.log
2   echo -e "**********************\n"   2>&1 | tee -a  out.log
3   
4   NBD=`sqlplus $dbconnection <<EOF | grep '^-' | sed 's/-//'
5   cl scr;
6   set serveroutput on;
7   set echo off;
8   set head off;
9   set termout off
10  set verify off
11  set feedback off
12  cl scr;
13  select '-'||sysdate from dual;
14  exit;
15  EOF`
16  
17  Error_code=`echo $?`
18  echo 
19  file_name=$1
20  
21  echo spoolfile = $file_name
22  echo $spoolfile
23  echo $spoolfile |cut -d'|' -f4 | read str4
24   echo 
25  exit 0

预期输出:run_new.sh 修改的行:1,2,18,24

1   logger "**********************"
2   logger -e "**********************"
3   
4   NBD=`sqlplus $dbconnection <<EOF | grep '^-' | sed 's/-//'
5   cl scr;
6   set serveroutput on;
7   set echo off;
8   set head off;
9   set termout off
10  set verify off
11  set feedback off
12  cl scr;
13  select '-'||sysdate from dual;
14  exit;
15  EOF`
16  
17  Error_code=`echo $?`
18  logger
19  file_name=$1
20  
21  echo spoolfile = $file_name
22  echo $spoolfile
23  echo $spoolfile |cut -d'|' -f4 | read str4
24   logger
25  exit 0

我在下面尝试过

shell_find_tee="2>&1"
f_in=run.sh
f_out=run_new.sh
# To remove line contains: $shell_find_tee
sed -e "s/$shell_find_tee.*//g" < $f_in > $f_out

#To find "echo" or "echo -e" replace by "logger"
shell_find_echo_main="echo"
shell_find_echo_main_e="echo.*-e"
shell_replace_echo="logger"

sed -e "s@$shell_find_echo_main_e@$shell_replace_echo@g" -e "s@$shell_find_echo_main@$shell_replace_echo@g" < $f_in > $f_out

但是这些命令将所有“ echo”替换为“ logger”,我不知道如何在“ sed”命令或任何其他方式中排除字符串模式。

有人可以帮我吗?

1 个答案:

答案 0 :(得分:1)

也许是这样的:

  1. 查找以$attributes = $item->children('g', true); foreach($attributes as $atrr) { echo "$attr<br />"; } 开头的行
    1. 如果它们仅包含(spaces)?echo( -e)?echo
      1. echo -e替换为echo
    2. 如果该行还包含logger
      1. 用记录器代替领先的回声
      2. 用单个空格替换2>&1\t
      3. 删除\n之后的所有内容

2>&1

对于测试用例来说似乎可以工作:

sed '
/^[[:space:]]*echo\([[:space:]]\+-e\)\?/{
     /^[[:space:]]*echo[[:space:]]\+\([[:space:]]\+-e\)\?[[:space:]]*$/{
           s/^\([[:space:]]*\)echo/\1logger/;
     };
     /2>&1/{
           s/^\([[:space:]]*\)echo/\1logger/;
           s/\\[tn]/ /g;
           s/[[:space:]]*2>&1.*//;
     }
 }'