
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 sed
Zeile:
sed -n '$j,4800p' IM_DlCtrlRef.txt >> IM_DlCtrlRef_bak
$j
Sie möchten die Shell-Variable in Ihrem sed
Skript als Startzeilennummer verwenden (das sed
Skript extrahiert Zeilen $j
bis 4800 aus einer Datei), verhindern jedoch, dass die Shell die Variable erweitert, indem Sie einfache Anführungszeichen verwenden. Dies bedeutet, dass als Startadresse sed
get 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 -r
wird grep
die Suche rekursiv durchgeführt, daher ist das hier wahrscheinlich nicht erforderlich. Ersetzen Sie es durch, -F
da 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 sed
Befehl =
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