Как заменить строку только в строках, соответствующих шаблону? - PullRequest
0 голосов
/ 08 апреля 2020

Я хочу заменить «stringA» на «stringB» во всех файлах, которые содержат шаблон, частью которого является stringA, и выполнять замену только в этих строках. Используя sed, я смог заменить строки во всем файле, а не с разрешением строки.

Например:

Я хочу заменить ip4_addr на dest_ip4_addr только в этих строках (если строка содержит stringA) из всех этих файлов:

sergey@ipkt /proj/sergey/platform (master) $ git grep -n ipkt_dp_filter_ipv4
ipkt-app/include/ipkt_dp_filter_api.h:7:ipkt_err_t ipkt_dp_filter_ipv4_add(uint16 vlan, uint32 ip4_addr, uint32 ip4_mask, bool is_stateful);
ipkt-app/include/ipkt_dp_filter_api.h:9:ipkt_err_t ipkt_dp_filter_ipv4_delete(uint16 vlan, uint32 ip4_addr, uint32 ip4_mask);
ipkt-app/ipkt-bm/ipkt_cmd.c:559:        SHR_IF_ERR_EXIT(ipkt_dp_filter_ipv4_add(vid, ip4_addr, ip4_mask, statefull_flag));
ipkt-app/ipkt-bm/ipkt_cmd.c:563:        SHR_IF_ERR_EXIT(ipkt_dp_filter_ipv4_delete(vid, ip4_addr, ip4_mask));
ipkt-app/ipkt-bm/ipkt_dp_filter_api.c:5:ipkt_err_t ipkt_dp_filter_ipv4_add(uint16 vlan, uint32 ip4_addr, uint32 ip4_mask, bool is_stateful)
ipkt-app/ipkt-bm/ipkt_dp_filter_api.c:13:ipkt_err_t ipkt_dp_filter_ipv4_delete(uint16 vlan, uint32 ip4_addr, uint32 ip4_mask)
ipkt-app/ipkt-rpc/server_rpc_wrappers.cpp:396:int rpc_ipkt_dp_filter_ipv4_add(uint16 vlan, std::string ip4_addr, uint32 mask, bool is_stateful){
ipkt-app/ipkt-rpc/server_rpc_wrappers.cpp:402:    CALL_IPKT(ipkt_dp_filter_ipv4_add(vlan, ipkt_ip, mask, is_stateful));
ipkt-app/ipkt-rpc/server_rpc_wrappers.cpp:405:int rpc_ipkt_dp_filter_ipv4_delete(uint16 vlan, std::string ip4_addr, uint32 mask){
ipkt-app/ipkt-rpc/server_rpc_wrappers.cpp:411:    CALL_IPKT(ipkt_dp_filter_ipv4_delete(vlan, ipkt_ip, mask));
ipkt-app/ipkt-rpc/server_rpc_wrappers.cpp:591:    srv.bind("ipkt_dp_filter_ipv4_add", &rpc_ipkt_dp_filter_ipv4_add);
ipkt-app/ipkt-rpc/server_rpc_wrappers.cpp:592:    srv.bind("ipkt_dp_filter_ipv4_delete", &rpc_ipkt_dp_filter_ipv4_delete);

То, что я пробовал:

grep -rl ipkt_dp_filter_ipv4 ipkt-app/ | grep -v swp | xargs sed -i 's/ip4_addr/dest_ip4_addr/'

Это изменило дополнительные строки, которые я не хотел менять.

git grep -l ipkt_dp_filter_ipv4 | xargs sed -i 's/ipkt_dp_filter_ipv4_.*uint32 /& dest_/'

Также пытался с регулярным выражением, но я не знаю, как заменить строку в регулярном выражении.

1 Ответ

0 голосов
/ 08 апреля 2020

с использованием awk

awk '{ if($0~/stringA/) gsub(/ip4_addr/,"dest_ip4_addr",$0)} 1 < input file'

Демо: заменить a там, где запись начинается с a

$echo -e  "abca\nefga\n123a"
abca
efga
123a
$echo -e  "abca\nefga\n123a"  | awk '{ if($0~/^a/) gsub(/a/,"d",$0)} 1' 
dbcd
efga
123a
$

...