如何替换由SED中的UNIX shell脚本同一文件中的行?(How to Replace a li

2019-07-21 18:00发布

在谈到这个问题越来越线路识别符匹配在第一和第二个文件后,我需要,我使用SED如下第二file.For线替换第一个文件就行了。 但只用sed替换一个新的文件该行。 我怎样才能实现无临时文件相同的文件更新(因为这些都是非常巨大的文件)。

#!/bin/ksh
while read line
do
var=`echo $line|cut -c 3-25`
while read i
do
var1=`echo $i|cut -c 3-25`
if [ $var == $var1 ];
then
sed -i s/$line/$i/ t1
else

echo "not matched"
fi
done < t2
done < t1

即使没有-i选项还我没有得到结果。 请帮我。

编辑 :要不给我建议没有临时文件或使用任何脚本语言(不太优选)做的任何其他最佳方式。

Answer 1:

你不应该使用sed这样。 当你的脚本现在站在这是这样说的:

  1. 对于t1每一行
  2. 通过T2的所有行步骤
  3. 如果在t2中的线路之一在T1当前行匹配,则通过在T1的所有行步骤和替换匹配
  4. 转到下一行t1和重复

这意味着,整个T2文件被读取每次一行被从t1读取。 这是令人难以置信的低效率。

这是没有必要使用echocut子字符串。 在bash和ksh,你可以这样做:

var=${line:3:23}

注意:剪裁采用了一系列的开头和结尾字符位置,而这个壳结构使用起始位置和字符数,所以你必须调整相应的数字。

如果T2在T1到进行替换的列表,从而T2是一个“脚本”不爽,那么这可能会做你的需要:

keystart=3
keylen=23
while read line
do
    var="${line:$keystart:$keylen}"
    if (( ${#var} == keylen ))    # need "$" then don't need "$"
    then
        sed -in "/^.\{$keystart\}$var/ c$line" t1    # use double-quote so vars get expanded
    fi
done < t2

这会发现在T1的所有行,在T2匹配每一行,并做了更换。

但是,如果t1和t2有一个线换线通信,你要只替换其中相应的线路匹配,这一点,使用临时文件,将是最有效的:

tempfile=$(mktemp)
keystart=3
keylen=23
while read line1
do
    var1="${line1:$keystart:$keylen}"
    read line2 <&3    # use file descriptor 3 for input

    var2="${line2:$keystart:$keylen}"
    if [[ $var1 == $var2 && ${#var2} == $keylen ]]
    then
        echo "${line2}" >> $tempfile    # substitute when matched
    else
        echo "${line1}" >> $tempfile    # keep when not matched
    fi
done < t1 3< t2    # t1 is input on stdin, t2 is input on fd 3
mv t1 t1.bak && mv $tempfile t1


Answer 2:

看看海绵这是一部分moreutils 。

% sed "s/root/toor/" /etc/passwd | grep -v joey | sponge /etc/passwd


Answer 3:

你可以不到位替换另一个一行。 因为线通常具有不同的长度,并且将彼此重叠。 如果你的文件中的所有行的长度相同,然后它可以工作。 我也建议你使用更合适的语言完成这个任务(如Perl为例),因为它会在壳牌进行非常复杂的代码。 我认为,你应该寻找颞文件的解决方案,因为它会更容易实现,它可以很容易地进行调试。 试想一下,你会怎么做,如果你巨大的文件将被currupted由于脚本错误。



Answer 4:

SED被设计成流水线工作 - 因此得名“流编辑器”。 相反,你可以使用一个前的脚本编辑文件到位。 EX是在其第六最初基于基于行的文本编辑器(不一样古老版,旧熊皮和石刀文本编辑器,但几乎)。 一个简单的例子,你可以修改你的目的可能如下:

ex t1 << EOF
$lineNum
s/^.*$/$newline/
w
q
EOF

该脚本首先将变成由$ LINENUM指示的线路,替代以$换行的内容,整条生产线开始(^)结束($),然后写入和退出。 这些命令由“包围<<EOF ”和“ EOF ”,这些构成了“这里”的文件,基本上建立脚本命令作为标准输入。



文章来源: How to Replace a line in the same file by SED in Unix Shell scripting?