匹配文本文件中同一行的多个模式,将行复制到下一行并修改字符串

匹配文本文件中同一行的多个模式,将行复制到下一行并修改字符串

我想在同一行上匹配文本文件(不同目录中)中的多个模式,将匹配的行复制到下一行并修改复制的行。我想复制包含字符串“businessServices”或“BusinessServices”的每一行。我不关心要匹配的模式出现在行中的位置。我想就地编辑文件。所需添加的行是这些全局替换:

s#businessServices#userServices#g and s#validate#test#g
s#BusinessServices#UserServices#g
s#BUSINESS_SERVICES#USER_SERVICES#g

文件1:

name="businessServices" value="validate"

所需文件 1:

name="businessServices" value="validate"
name="userServices" value="test"

文件2:

public static final String BUSINESS_SERVICES = "businessServices";

所需文件2:

public static final String BUSINESS_SERVICES = "businessServices";
public static final String USER_SERVICES = "userServices";

文件3:

import com.my.ClientBusinessServicesRequest;
import com.my.ClientBusinessServicesResponse;

ClientBusinessServicesRequest clientBusinessServicesRequest = new ClientBusinessServicesRequest();
ClientBusinessServicesResponse clientBusinessServicesResponse = new ClientBusinessServicesResponse();

所需文件3:

import com.my.ClientBusinessServicesRequest;
import com.my.ClientBusinessServicesResponse;
import com.my.ClientUserServicesRequest;
import com.my.ClientUserServicesResponse;

ClientBusinessServicesRequest clientBusinessServicesRequest = new ClientBusinessServicesRequest();
ClientBusinessServicesResponse clientBusinessServicesResponse = new ClientBusinessServicesResponse();
ClientUserServicesRequest clientUserServicesRequest = new ClientUserServicesRequest();
ClientUserServicesResponse clientUserServicesResponse = new ClientUserServicesResponse();

file3 不太想要(如果 file3 想要的太难实现):

import com.my.ClientBusinessServicesRequest;
import com.my.ClientUserServicesRequest;
import com.my.ClientBusinessServicesResponse;
import com.my.ClientUserServicesResponse;

ClientBusinessServicesRequest clientBusinessServicesRequest = new ClientBusinessServicesRequest();
ClientUserServicesRequest clientUserServicesRequest = new ClientUserServicesRequest();
ClientBusinessServicesResponse clientBusinessServicesResponse = new ClientBusinessServicesResponse();
ClientUserServicesResponse clientUserServicesResponse = new ClientUserServicesResponse();

我尝试了以下方法,每一种都得到了一些期望的结果,但不是全部期望的结果。

grep -rl businessServices . | xargs sed -i 's#\(.*\)validate\(.*\)#&\n\1test\2#' 

grep -rl businessServices . | xargs sed -i 's#\(.*\)businessServices\(.*\)#&\n\1userServices\2#'

grep -rl BusinessServices . | xargs sed -i 's#\(.*\)BusinessServices\(.*\)#&\n\1UserServices\2#g'

grep -rli businessServices . | xargs sed -i 's#\(.*\)BUSINESS_SERVICES\(.*\)#&\n\1USER_SERVICES\2#' 

答案1

使用 GNU sed we 并在扩展正则表达式模式 (-E) 下,无自动打印 (-n) 和就地编辑 (-i)

sed -Eni '
  /[bB]usinessServices|BUSINESS_SERVICES/{
    h
    :loop
      ${g;bend;}
      n
    //{H;bloop;}
    x
    :end
    p'"
    $(< cmds.sed)
    "'
    $!G
  }
  p
' file3

  • 使用 OR 正则表达式选择所需的行。
  • 然后开始循环以将连续的所需行存储在保持中
  • 打印存储在hold中的一堆连续行。
  • 然后通过插入存储在文件(cmds.sed)中的 sed 命令来执行替换操作
  • 打印修改后的一堆+保留的任何内容。

cmds.sed 文件的内容:

$ cat cmds.sed

s#businessServices#userServices#g

s#validate#test#g

s#BusinessServices#UserServices#g

s#BUSINESS_SERVICES#USER_SERVICES#g

答案2

使用 GNU awk 进行“就地”编辑ENDFILE,只需缓冲更改的行,直到遇到空行或文件末尾,然后打印它们:

$ awk -i inplace '
    !NF {
        printf "%s", buf
        buf = ""
    }
    {
        print
        orig = $0
        gsub(/businessServices/,"userServices")
        gsub(/validate/,"test")
        gsub(/BusinessServices/,"UserServices")
        gsub(/BUSINESS_SERVICES/,"USER_SERVICES")
    }
    $0 != orig {
        buf = buf $0 ORS
    }
    ENDFILE {
        printf "%s", buf
        buf = ""
    }
' file1 file2 file3

$ head file1 file2 file3
==> file1 <==
name="businessServices" value="validate"
name="userServices" value="test"

==> file2 <==
public static final String BUSINESS_SERVICES = "businessServices";
public static final String USER_SERVICES = "userServices";

==> file3 <==
import com.my.ClientBusinessServicesRequest;
import com.my.ClientBusinessServicesResponse;
import com.my.ClientUserServicesRequest;
import com.my.ClientUserServicesResponse;

ClientBusinessServicesRequest clientBusinessServicesRequest = new ClientBusinessServicesRequest();
ClientBusinessServicesResponse clientBusinessServicesResponse = new ClientBusinessServicesResponse();
ClientUserServicesRequest clientUserServicesRequest = new ClientUserServicesRequest();
ClientUserServicesResponse clientUserServicesResponse = new ClientUserServicesResponse();

答案3

我认为这可以满足您对两个的要求sed

$ sed -e 's/.*business.*\|.*Business.*/&\n&/' \
    -e 's/business/user/g2' \
    -e 's/BUSINESS/USER/2' \
    -e '/^import com.my.ClientBusinessServicesResponse/s/Business/User/2' \
    -e '/^ClientBusinessServicesResponse/s/Business/User/4g' file1 file2 file3

# file1
name="businessServices" value="validate"
name="userServices" value="validate"

# file2
public static final String BUSINESS_SERVICES = "businessServices";
public static final String USER_SERVICES = "userServices";

# file3
import com.my.ClientBusinessServicesResponse;
import com.my.ClientUserServicesResponse;

ClientBusinessServicesResponse clientBusinessServicesResponse = new ClientBusinessServicesResponse();
ClientUserServicesResponse clientUserServicesResponse = new ClientUserServicesResponse();

最后

$ sed '/userServices/s/validate/test/' file1

相关内容