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

$jスクリプト内のシェル変数をsed開始行番号として使用したいのですが(スクリプトはファイルから 4800 行までを抽出します)、一重引用符を使用してシェルが変数を展開できないようにしています。これは、sed開始アドレスとして取得されることを意味し、混乱を招きます。$jsed$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

これには、修正したいかどうかわからないスタイルの問題とパフォーマンスの問題がいくつかあります。

forまず、すべての行番号を変数に読み込みます。これはメモリの無駄ですが、 -loop がループする対象を正確に知る必要があるため、これを行う必要があります。

別の解決策としては、行番号を 1 つずつ読み取ることです。

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

関連情報