使用行范围进行多次替换

时间:2016-10-07 10:06:37

标签: bash shell unix sed

我有一个包含以下记录的文件

user1,fuser1,luser1,user1@test.com,data,user1
user2,fuser2,luser2,user2@test.com,data,user2
user3,fuser3,luser3,user3@test.com,data,user3

我想从

执行一些文本替换

用户1,fuser1,luser1,USER1 @ test.com,数据,用户1

New_user1,New_fuser1,New_luser1,New_user1 @ test.com,数据,New_user1

所以我写了下面的sed脚本。

sed -i -e 's/user/New_user/g; s/fuser/New_fuser/g; s/luser/New_luser/g' file

这很完美。现在我要求在特定的行范围内替换。

start=2
end=3
sed -i -e ''${start},${end}'s/user/New_user/g; s/fuser/New_fuser/g; s/luser/New_luser/g' file

但是这个命令正在替换所有行中的模式。示例输出是,

user1,New_fuser1,New_luser1,user1@test.com,data,New_user1
user2,New_fuser2,New_luser2,user2@test.com,data,New_user2
user3,New_fuser3,New_luser3,user3@test.com,data,New_user3

看起来范围仅应用于第一个表达式,其余表达式将应用于整个文件。如何将此范围应用于所有表达式?

4 个答案:

答案 0 :(得分:1)

您可以使用#Пример()变量来使用此功能,控制用于替换的行号和列号

awk

其中awk -vFS="," -vOFS="," -v columnStart=2 -v columnEnd=3 -v rowStart=1 -v rowEnd=2 \ 'NR>=rowStart&&NR<=rowEnd{for(i=columnStart; i<=columnEnd; i++) \ $i="New_"$i; print }' file 变量awkcolumnStartcolumnEndrowStart确定要用rowStart替换哪些列和行作为de - 限制采用。

输入文件: -

,

假设我想在第3-4列的第2行和第3行中进行替换,我可以将$ cat input-file user1,fuser1,luser1,user1@test.com,data,user1 user2,fuser2,luser2,user2@test.com,data,user2 user3,fuser3,luser3,user3@test.com,data,user3 设置为

awk

要申请最后一栏,请将awk -vFS="," -vOFS="," -v columnStart=3 -v columnEnd=4 -v rowStart=2 -v rowEnd=3 \ 'NR>=rowStart&&NR<=rowEnd{for(i=columnStart; i<=columnEnd; i++) \ $i="New_"$i; print }' file user2,fuser2,New_luser2,New_user2@test.com,data,user2 user3,fuser3,New_luser3,New_user3@test.com,data,user3 columnStart设置为相同的值,例如请参阅第6列和最后行。

columnEnd

答案 1 :(得分:0)

以下适用于我:

START=2
NUM=1
sed -i -e "$START,+${NUM} s/user/New_user/g; $START,+${NUM} s/fuser/New_fuser/g; $START,+${NUM}  s/luser/New_luser/g" file

如您所见,有几处变化:

  1. 每个表达式都必须出现行范围
  2. 范围应表示(在本例中)作为起始行号和行数(受影响的行数为NUM + 1)
  3. 你放了额外的撇号符号。

答案 2 :(得分:0)

使用单个s命令:

start=1
end=2
sed -e "$start,$end s/\([fl]*\)user/New_\1user/g" file

[fl]*user会将user与可选的fl首字母匹配

<强>输出:

New_user1,New_fuser1,New_luser1,New_user1@test.com,data,New_user1
New_user2,New_fuser2,New_luser2,New_user2@test.com,data,New_user2
user3,fuser3,luser3,user3@test.com,data,user3

答案 3 :(得分:0)

使用GNU Sed时(在Ubuntu上,可能在Debian上,以及其他上可以使用)。

有一个功能可以简化此操作: https://www.gnu.org/software/sed/manual/sed.html#Common-Commands

一组命令可以放在{和}字符之间。这个 当您想要一组命令时特别有用 由单个地址(或地址范围)匹配触发。

示例:执行替换,然后打印第二行输入:

$ seq 3 | sed -n '2{s/2/X/ ; p}'
X

鉴于最初的问题,这应该可以解决问题:

sed -i -e '2,3 {s/user/New_user/g; s/fuser/New_fuser/g; s/luser/New_luser/g}' file