2015-07-09 5 views
-1

У меня есть цикл bash, перемещающийся по строкам в файле, и мне интересно, есть ли способ интерактивно заменить каждую строку содержимым.замена интерактивной строки bash

while read p 
do 
    echo $p 
    read input 
    if [ "$input" == "y" ]; then 
     # DO SOME ON P REPLACEMENT HERE 
done<$fname 

Из чтения (3) я знаю, что прочитал копии из дескриптора файла в * буфер. Я понимаю, что я могу использовать подстановку sed напрямую, но не могу заставить ее работать в этом контексте цикла bash. Например, сказать, что я хочу, чтобы обернуть выбранные строки:

sed 's/\(.*\)/wrap \(\1\)/' 

Усложнение: баш «читать» Команда съедает «\» и продолжает чтение «линии» (это то, что я ищу). Сед, похоже, НЕ. Это означает, что количество строк будет различным, поэтому наивный счетчик, похоже, не подходит, если нужно работать с sed.

+0

почему бы вам не использовать текстовый редактор? – 123

+0

sed - текстовый редактор. этот скрипт будет запущен на довольно минимальном сервере. ищет некоторый уровень автоматизации. – djh

+1

нет, это не так. У вас нет vi или emacs или что-то еще? – 123

ответ

0

Я не уверен, что понимаю, что вам нужно, и, возможно, вы можете дать нам более подробную информацию, например, пример ввода и ожидаемый результат. Может быть, это полезно?

while read p 
do 
    echo "$p" 
    read input 
    if [ "$input" == "y" ] 
    then 
     # Sed is fed with "p" and then it replaces any input with a given string. 
     # In this case "wrap <matched_text>". Its output is then assigned again to "p" 
     p="$(sed -nre 's/(.*)/wrap \1/p' <<< "$p")" 
    fi 
done < "$fname" 
+0

Возможно, мне не хватает лодки. Это просто напечатает новый p, дополненный sed. Правильно? Я ищу, чтобы написать обратно в файл. Наверное, с кучей дорогих, зацикленных системных вызовов ... но, тем не менее. – djh

+0

Как я уже сказал, я не был уверен, что понял вопрос. Bash не может писать в файле, который открыт для чтения: https://stackoverflow.com/questions/6696842/bash-redirect-input-from-file-back-into-same-file. Затем вы можете написать измененный «p », и все, что вам нужно, в другом файле, а затем переименуйте его. Для простых замен вы можете использовать только sed без скрипта bash. Http://www.refining-linux.org/archives/27/20-Multi-line-sed-search-and-replace/ – ColOfAbRiX

+1

@dagan: Обычный трюк заключается в создании второго файла на основе содержимого файла, который вы читаете. Тогда, если все будет успешным, просто «mv» заменит исходный файл. – slebetman

1

Использование ex, который не является визуальным режимом vim (это как новая ed):

ex -c '%s/\(.*\)/wrap \(\1\)/c' FILE 

Обратите внимание, что мне нужно, чтобы добавить % (сделать операцию для всех линий) и c (запрос перед заменой) в начале и конце вашего выражения sed, соответственно.

При появлении запроса введите y<CR>, чтобы заменить, n<CR>, чтобы заменить, q<CR>, чтобы остановить замену команды. После ввода q<CR> или достижения конца файла вы можете сохранить изменения с помощью w<CR> (что перезапишет файл) и выйти с q<CR>.

В качестве альтернативы вы можете использовать ed, но я не буду вам этого помогать. ;)

Для получения более подробной информации о ex, проверить этот вопрос:

https://superuser.com/questions/22455/vim-what-is-the-ex-mode-for-batch-processing-for

+0

Для получения дополнительной информации о 'ed': http://www.gnu.org/fun/jokes/ed-msg.html. – werkritter

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