sed -n [duplicate]を使用するとsed -n '$ j,4800p'でエラーが発生するのはなぜですか?

sed -n [duplicate]を使用すると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ファイルからsed行4800を抽出します)、一重引用符を使用してシェルが変数を拡張するのを防ぎます。$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

これには、変更したくない場合や修正したくない可能性があるいくつかのスタイルの問題とパフォーマンスの問題があります。

まず、すべての行番号を変数として読み込みます。これはメモリの無駄ですが、-loopはfor何を繰り返すかを正確に知る必要があるため、これを行う必要があります。

別の解決策は、行番号を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

関連情報