2017-01-19 9 views
2

Это скрипт, который помогает нам создать файл dhcpd.conf.Bash: Невозможно добавить строку в существующую строку - вместо этого она перезаписывает начало этой строки.

входы выборки (язычок Mac ех -; - вкладка-IP.)

DC:D3:21:75:61:90 ; 10.25.131.17 
    ; 

Ожидаемые результаты

Host 27-48 { hardware ethernet DC:D3:21:75:61:90 ; fixed-address 10.25.131.17 ; } 

#host 27-48 { hardware ethernet ; fixed-address ; } 

В настоящее время линия, выводимый заключается в следующем:

Host 27-48 { hardware ethernet 00:16:6B:C8:3D:C9 ; fixed-address 10.25.129.185 

Удельная строка в коде Я застрял на

outputLine="Host $((names[i]))-$((startingNumber+counter)) { hardware ethernet $first ; fixed-address $second" 

Если я попробую добавить; }

outputLine="Host $((names[i]))-$((startingNumber+counter)) { hardware ethernet $first ; fixed-address $second ; }" 

я получаю это:

; } 27-48 { hardware ethernet 00:16:6B:C8:3D:C9 ; fixed-address 10.25.129.185 

Вопрос в том, когда я добавить «;}» к концу предыдущей строки, она переписывает начало строки. Я пробовал несколько трюков, чтобы обойти это, например, написать вышеприведенную строку в строку, а затем попытаться добавить к строке, но та же проблема возникает. У меня возникла идея экспортировать все содержимое в файл и повторно перезагрузить файл в массив, чтобы я мог добавить его, но он кажется немного переборщиком.

for ((j=1; j<=${sizes[i]}; j++)); do 

    #split line, read split as two entries for an arrIN 
    IN=(${line[counter+1]}) 
    arrIN=(${IN//;/ }) 
    first="${arrIN[0]}" 
    second=${arrIN[1]} 


    if [ ${lineSize[counter+1]} -gt 5 ] 
    then 
     #sed 's/$/ ; }/' $outputLine > newoutputLine 
     outputLine="Host $((names[i]))-$((startingNumber+counter)) { hardware ethernet $first ; fixed-address $second" 
     echo $outputLine 
    else 
     echo "#host $((names[i])) $((startingNumber+counter)) { hardware ethernet ; fixed-address ; }" 
    fi 
    counter=$((counter+1)) 
done 
+1

Попробуйте напечатать '$ second' - может быть есть что-то смешное в конце' $ {arrIN [1]} ' – mustaccio

+0

Государственные ваши входные переменные четко и обеспечивают точный ожидаемый выход. Ваш код 'bash' создает файл' dhcpd.conf' или вы просто хотите отредактировать этот файл на месте с помощью '; } 'в конце? – Inian

+0

обновленный образец ввода. Bash-код не создает dhcpd.conf, а только его часть, которая в конечном итоге будет объединена с частью подсети (то есть скопировать и вставить). Один выход уже предоставлен, будет обновлять вывод для другого «пустого случая» – thistleknot

ответ

2

В ruakh объясняет в комментарии по этому вопросу, то проблема была CR (0xD, \r) символ в конце значения переменной $second, который можно удалить с помощью следующего parameter expansion: second="${second//$'\r'/}".

Остальная часть этого ответа объясняет симптом и предоставляет справочную информацию.


Этот вопрос, всякий раз, когда я добавить «;}» к концу указанной выше линии, она переписывает начало строки.

«перезапись начало строки» почти всегда указывает на встроенный CR (0xD, \r) характер, что, когда строка выводится на терминал, дает вид перезаписывания начало линии:

$ printf 'abc\rd' # `printf '\r'` produces a CR 
dbc # It LOOKS LIKE 'd' replaced 'a', but that's an artifact of printing to the terminal. 

Это только потому, что терминал интерпретирует CR (\r) в качестве «поместить курсор в начало строки», что d - остальные строки аф ter \r - появляется «перезаписать» начало уже отпечатанной части строки.

Вы можете визуализировать встроенные CRs (и другие управляющие символы) с cat -et, который представляет их в caret notation, как ^M:

$ printf 'abc\rd' | cat -et 
abc^Md # ^M represents a CR (\r) 

Как вы можете видеть, d фактически не перезаписьa, начало строки.


CR (\r) экземпляры редко используются в мире Unix обработки текста. Если они появляются как часть текстовых данных, обычно это от Windows - источники, которые используют концы строк CRLF (\r\n), а не окончания линий Unix LF-only (\n).

Часто, самый простой подход, чтобы просто удалить ЧР (\r) экземпляры перед тем с использованием данных с Unix утилит.

Есть много, много существующих ответов, которые покрывают эту территорию, часто рекомендует использовать сторонних утилита dos2unix, легко устанавливаемые с помощью менеджеров пакетов многих платформ (например, sudo apt install dos2unix на Ubunutu или brew install dos2unix на MacOS, с помощи Homebrew).

В качестве альтернативы,

  • для текста уже хранится в переменной, используйте ruakh «ы подход, основанный на разложении параметра; например, second="${second//$'\r'/}"

  • для файлов, solutions using standard utilities может выступать в качестве импровизированного dos2unix.

 Смежные вопросы

  • Нет связанных вопросов^_^