當我使用 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

您希望$jsed腳本中使用 shell 變數作為起始行號(腳本從檔案中sed提取到第 4800 行),但您透過使用單引號來阻止 shell 擴展該變數。$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

這有一些您可能想要或可能不想修復的樣式問題和效能問題。

首先,將所有行號讀入變數。這是浪費內存,但您需要這樣做,因為 -loopfor需要確切地知道要循環的內容。

另一種解決方案是逐一讀取行號:

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

相關內容