cuando usé sed -n, ¿por qué este error es acerca de sed -n '$j,4800p'

cuando usé sed -n, ¿por qué este error es acerca de 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

Respuesta1

Su principal problema (el que provoca un error de sintaxis) radica en la sedlínea:

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

Desea utilizar la variable de shell $jen su sedsecuencia de comandos como número de línea de inicio (la sedsecuencia de comandos extrae líneas $jhasta 4800 de un archivo), pero evita que el shell expanda la variable usando comillas simples. Esto significa que sedobtendrá $jcomo dirección inicial, lo que la confundirá sin límites.

Simplemente cambie esa línea para que tenga comillas dobles.

Ahora, mirando el guión completo:

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

Esto tiene algunos problemas de estilo y de rendimiento que quizás quieras solucionar o no.

En primer lugar, lee todos los números de línea en una variable. Esto es una pérdida de memoria, pero es necesario hacerlo porque el forbucle necesita saber exactamente qué recorrer.

Otra solución sería leer los números de línea uno por uno:

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

Esto significa que no hay límite en la cantidad de datos que el script puede absorber.

Por cierto, -rrealiza grepla búsqueda de forma recursiva, por lo que probablemente no sea necesario aquí. Reemplácelo con -Fya que está buscando una cadena fija (no una expresión regular).

Sin embargo, dado que solo le interesan los números de línea de las líneas que coinciden #32, puede reemplazar toda esa tubería con

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

El sedcomando =imprime números de línea.

Con una última ronda de retoques, el guión se vuelve

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

información relacionada