当我使用 sed -n 时,为什么 sed -n ' $j,4800p' 会出错

当我使用 sed -n 时,为什么 sed -n ' $j,4800p' 会出错
LINEnum=$(grep -nr "#32" IM_DlCtrlRef.txt | cut -d : -f 1)
for j in $LINEnum
do
    echo $j
    sed -n '$j,4800p'  IM_DlCtrlRef.txt >> IM_DlCtrlRef_bak
    for insertl in {1..4}
    do
        cat zero.txt >> IM_DlCtrlRef_bak
    done
done

答案1

您的主要问题(导致语法错误的问题)在于sed

sed -n '$j,4800p'  IM_DlCtrlRef.txt >> IM_DlCtrlRef_bak

您希望$jsed脚本中使用 shell 变量作为起始行号(脚本从文件中sed提取到第 4800 行),但您通过使用单引号阻止 shell 扩展该变量。$j这意味着sed将获取$j作为起始地址,这将使其混乱无止境。

只需将该行更改为双引号即可。

现在,看看完整的脚本:

LINEnum=$(grep -nr "#32" IM_DlCtrlRef.txt | cut -d : -f 1)
for j in $LINEnum
do
    echo $j
    sed -n "$j,4800p"  IM_DlCtrlRef.txt >> IM_DlCtrlRef_bak
    for insertl in {1..4}
        do
    cat zero.txt >> IM_DlCtrlRef_bak
        done
done

这有一些您可能想要或可能不想修复的样式问题和性能问题。

首先,将所有行号读入变量。这是浪费内存,但您需要这样做,因为 -loopfor需要确切地知道要循环的内容。

另一种解决方案是逐个读取行号:

grep -nr "#32" IM_DlCtrlRef.txt | cut -d : -f 1 |
while read j; do
   # ...
done

这意味着脚本能够吞入的数据量没有限制。

顺便说一句,递归地-r进行grep搜索,所以这里可能不需要。将其替换为,-F因为您正在寻找固定字符串(而不是正则表达式)。

但是,由于您只对匹配的行的行号感兴趣#32,因此您可以将整个管道替换为

sed -n '/#32/=' IM_DlCtrlRef.txt

sed命令=打印行号。

经过最后一轮润色,脚本变成

sed -n '/#32/=' IM_DlCtrlRef.txt |
while read j; do
    echo $j
    sed -n "$j,4800p" IM_DlCtrlRef.txt >>IM_DlCtrlRef_bak
    for insertl in {1..4}; do
        cat zero.txt >>IM_DlCtrlRef_bak
    done
done

相关内容