从文件中的一组字符串替换字符串 - SED

时间:2017-11-23 13:17:31

标签: linux bash shell loops sed

我在从File中替换来自一组字符串的字符串时遇到了麻烦 所以这就是我希望我的脚本运行的方式

我有这些文件: macadd.file

host Accountant { hardware ethernet 00:90:8F:56:63:88; fixed-address 192.168.10.29; }
host Accountant { hardware ethernet 00:90:8F:56:63:88; fixed-address 192.168.10.29; }
host Accountant { hardware ethernet 00:90:8F:56:63:88; fixed-address 192.168.10.29; }
host Accountant { hardware ethernet 00:90:8F:56:63:88; fixed-address 192.168.10.29; }
host Accountant { hardware ethernet 00:90:8F:56:63:88; fixed-address 192.168.10.29; }
host Accountant { hardware ethernet 00:90:8F:56:63:88; fixed-address 192.168.10.29; }

TEST.FILE

for i in $(cat macadd); do sed -i "s/00:90:8F:56:63:88/$i/g" test;done

所以我尝试用

替换它
host Accountant { hardware ethernet 00:90:8F:56:63:88; fixed-address 192.168.10.29; }
host Accountant { hardware ethernet 00:90:8F:56:63:77; fixed-address 192.168.10.29; }
host Accountant { hardware ethernet 00:90:8F:56:63:6B; fixed-address 192.168.10.29; }
host Accountant { hardware ethernet 00:90:8F:56:63:86; fixed-address 192.168.10.29; }
host Accountant { hardware ethernet 00:90:8F:56:63:87; fixed-address 192.168.10.29; }
host Accountant { hardware ethernet 00:90:8F:56:64:E5; fixed-address 192.168.10.29; }

但是,它只会从macadd.file中的第一个字符串更改它 你可以看到00:90:8F:56:63:88就是那里的所有条目。我想要发生的是这样的结果:

Laravel

4 个答案:

答案 0 :(得分:1)

实际上,对于你在问题中提出的例子,没有替换的东西会更简单明了:

<macadd.file xargs -I{} printf "host Accountant { hardware ethernet %s; fixed-address 192.168.10.29; }\n" {}

这是输入文件中的每一行调用printf来仅替换MAC地址部分。如果您有更多的MAC地址和更多的IP地址,就会遇到更多麻烦。

答案 1 :(得分:0)

第一次传递导致sed以第一个值替换所有命中。如果这不是您想要的,请使用其他sed脚本。也许是这样的:

sed 's!.*!s/00:90:8F:56:63:88/&/;n;!' macadd.file

这会在标准输出上生成一个新的sed脚本,您可以将其传递给(...暂停...)sed

sed 's!.*!s/00:90:8F:56:63:88/&/;n;' macadd.file |
sed -f - -i test.file

这是第一次看到它时稍微苛刻的模式(并且sed -f -在所有平台上都不起作用)但是一旦你明白了,让脚本生成脚本是一个非常强大和多功能的工具你的工具箱。

...在MacOS上,您无法使用sed -f --i也需要参数。如果你有Bash(或其他一些支持进程替换的shell),这里有一个解决方法:

sed -f <(sed 's!.*!s/00:90:8F:56:63:88/&/;n;!' macadd.file) -i '' test.file

答案 2 :(得分:0)

直接使用 AWK

awk 'NR==FNR{ a[NR]=$1; next }
     a[FNR]{ sub("00:90:8F:56:63:88", a[FNR]) }1' macadd tesfile > tmp_f && mv tmp_f testfile
  • NR - 到目前为止读取的输入记录总数
  • FNR - 到目前为止从当前输入文件中读取的记录数

最终testfile内容:

host Accountant { hardware ethernet 00:90:8F:56:63:88; fixed-address 192.168.10.29; }
host Accountant { hardware ethernet 00:90:8F:56:63:77; fixed-address 192.168.10.29; }
host Accountant { hardware ethernet 00:90:8F:56:63:6B; fixed-address 192.168.10.29; }
host Accountant { hardware ethernet 00:90:8F:56:63:86; fixed-address 192.168.10.29; }
host Accountant { hardware ethernet 00:90:8F:56:63:87; fixed-address 192.168.10.29; }
host Accountant { hardware ethernet 00:90:8F:56:64:E5; fixed-address 192.168.10.29; }

答案 3 :(得分:0)

如果test.file中的MAC地址并不总是相同 你可以尝试:

sed -E '
s/((([[:xdigit:]]){2}:){5}[[:xdigit:]]{2})(.*)((([[:xdigit:]]){2}:){5}[[:xdigit:]]{2})(.*)/\4\1\8/
# ((([[:xdigit:]]){2}:){5}[[:xdigit:]]{2}) catch the MAC addresse
s/^\t//
# remove tab which come from paste
/^((([[:xdigit:]]){2}:){5}[[:xdigit:]]{2})/d
# remove lines if maccad.file have more lines than test.file
'<<< $(paste macadd.file test.file)>test.file