когда я использовал 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скрипте как начальный номер строки ( sedскрипт извлекает строки $jдо 4800 из файла), но вы не даете оболочке расширить переменную, используя одинарные кавычки. Это означает, что sedget будет $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должен точно знать, что именно нужно перебрать.

Другим решением было бы прочитать номера строк одну за другой:

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

Связанный контент