Text-Processing

匹配同一行文本文件中的多個模式,將行複製到下一行並修改字元串

  • December 25, 2021

我想在同一行上匹配文本文件(在不同目錄中)中的多個模式,將匹配的行複製到下一行並修改複製的行。我想複製包含字元串“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#' 

使用 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();

使用 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 正則表達式選擇所需的行。
  • 然後開始一個循環以將連續的所需行儲存在保持中
  • 列印儲存在保持中的一堆連續行。
  • 然後通過插入儲存在文件 (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

引用自:https://unix.stackexchange.com/questions/683692