als ich sed -n verwendet habe, warum dieser Fehler bezüglich sed -n ' $j,4800p'

als ich sed -n verwendet habe, warum dieser Fehler bezüglich 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

Antwort1

Ihr Hauptproblem (das einen Syntaxfehler verursacht) liegt in der sedZeile:

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

$jSie möchten die Shell-Variable in Ihrem sedSkript als Startzeilennummer verwenden (das sedSkript extrahiert Zeilen $jbis 4800 aus einer Datei), verhindern jedoch, dass die Shell die Variable erweitert, indem Sie einfache Anführungszeichen verwenden. Dies bedeutet, dass als Startadresse sedget wird , was es verwirren würde, keine Enden zu haben.$j

Ändern Sie diese Zeile einfach so, dass sie stattdessen Anführungszeichen enthält.

Sehen wir uns nun das vollständige Skript an:

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

Dies bringt einige Stil- und Leistungsprobleme mit sich, die Sie möglicherweise beheben möchten, vielleicht aber auch nicht.

Zuerst liest man alle Zeilennummern in eine Variable ein. Das ist zwar Speicherverschwendung, aber notwendig, weil die for-Schleife genau wissen muss, was sie durchlaufen soll.

Eine andere Lösung wäre, die Zeilennummern einzeln zu lesen:

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

Dies bedeutet, dass es hinsichtlich der Datenmenge, die das Skript verarbeiten kann, keine Begrenzung gibt.

Übrigens -rwird grepdie Suche rekursiv durchgeführt, daher ist das hier wahrscheinlich nicht erforderlich. Ersetzen Sie es durch, -Fda Sie nach einer festen Zeichenfolge (kein regulärer Ausdruck) suchen.

Da Sie jedoch nur an den Zeilennummern der übereinstimmenden Zeilen interessiert sind #32, können Sie die gesamte Pipe durch ersetzen.

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

Der sedBefehl =druckt Zeilennummern.

Mit einer letzten Überarbeitung wird das Skript

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

verwandte Informationen