我有三个文件,两个文件,每个文件有2259个IP地址。一个文件包含137772.该脚本使用带有bash数组的sed和一个for循环来替换具有不同IP的access.log中的IP。运行几个小时后,脚本失败并显示以下错误:
sed:-e表达式#1,字符0:没有先前的正则表达式
uniq IP地址的数量也短6个IP。
这是脚本:
#!/bin/bash
_ORGIFS=$IFS
IFS=$'\n'
_alIPs=($(<access.log.IPs)
_fIPs=($(<randomIPs.txt)
for (( _i=1; _i<=2259; _i++ ))
do
sed -i "s/${_alIPs[$_i]}/${_fIPs[$_i]}/g" access.log
done
IFS=$_ORGIFS
答案 0 :(得分:3)
bash中的数组索引从0开始。当你说
时for (( _i=1; _i<=2259; _i++ ))
你忽略了第一个条目,然后过了一个结束,此时
sed -i "s/${_alIPs[$_i]}/${_fIPs[$_i]}/g" access.log
扩展为
sed -i "s//something/g" access.log
//
命令中的s
尝试重用以前使用的不存在的正则表达式,因此您会收到错误。
解决方案是使用
for (( _i=0; _i<2259; _i++ ))
......但是,严肃地说,我会花一些时间考虑如何批量进行这些替换。
附录:例如
sed -i -f <(paste access.log.IPs randomIPs.txt | awk '{ print "s/" $1 "/" $2 "/g" }') access.log
(假设我正确地读了你的意图)
答案 1 :(得分:0)
这取自我自己的bash模板lib根据需要使用:
# parse a template and return it
# 1st arg is template tags [array]
# 2nd arg is replacement values for template tags [array]
# 3rd arg is template file path
# usage: TT=$(parseTemplate TAGS[@] REPLACE[@] $MAIL_TEMPLATE); echo $TT;
function parseTemplate()
{
local _TAG=("${!1}")
local _REPLACE=("${!2}")
local _TEMPLATE="${3}"
local _PATTERN=""
local i
if [[ ${#_TAG[@]} > 0 ]]; then
_PATTERN="-e s#\%\%${_TAG[0]}\%\%#${_REPLACE[0]}#g"
for (( i = 1 ; i < ${#_TAG[@]} ; i++ ))
do
_PATTERN="${_PATTERN}; s#\%\%${_TAG[${i}]}\%\%#${_REPLACE[${i}]}#g"
done
local SED=`which sed`
$SED "${_PATTERN}" < "${_TEMPLATE}"
else
local CAT=`which cat`
$CAT "${_TEMPLATE}"
fi
}
模板替换标签具有以下格式:%%TAG%%
可以更改此格式,但这是此功能使用的
示例模板(文件或文本):
Hello %%NAME%%, your location is %%LOCATION%%
TAGS = ('NAME' 'LOCATION');
REPLACE = ('Nikos' 'GR')
TT=$(parseTemplate TAGS[@] REPLACE[@] $MAIL_TEMPLATE);
echo $TT;