使用bash数组的sed find replace失败

时间:2015-04-07 09:16:18

标签: bash sed

我有三个文件,两个文件,每个文件有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

2 个答案:

答案 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;

http://www.thegeekstuff.com/2010/06/bash-array-tutorial/