我想在同一行上匹配文本文件(不同目录中)中的多个模式,将匹配的行复制到下一行并修改复制的行。我想复制包含字符串“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