Невозможно заменить строку из файла во время итерации - PullRequest
0 голосов
/ 19 сентября 2018

final.txt выглядит следующим образом:

build/create_changes.sh
build/create_changes.sh-meta.xml
src/aura/camping/camping.design
src/aura/camping/camping.design-meta.xml

Я хотел бы заменить только те файлы, которые содержат /aura/ в своей строке, на src/aura/camping

if [ -e final.txt ]
then
        ARRAY=()
        while read CFILE
            do
                    echo Analyzing file `basename $CFILE`
                    case "$CFILE"
                    in
                        *.design) TYPENAME="AuraDefinitionBundle";;
                        *) TYPENAME="UNKNOWN";;
                    esac

                    if [ "$TYPENAME" == "AuraDefinitionBundle" ]
                        then
                                if [ $(contains "${ARRAY[@]}" $(basename -- "$(dirname -- "$CFILE")")) != "y" ]
                                then
                                    echo baseFile from new method cFile $CFILE
                                    CFILENAME="$CFILE"

                                    replace="src/aura/"$(basename -- "$(dirname -- "$CFILE")")
                                    echo checkChanges "${CFILENAME/$CFILENAME/"$replace"}"
                                    CFILE="${CFILENAME/$CFILENAME/"$replace"}"
                                    echo baseFile from after change method cFile $CFILE
                                else
                                    continue
                                fi
                        fi
            done < final.txt
else
echo Change file not found!

Этоработает, так что теперь я вижу это в окне:

 [exec] baseFile from new method cFile src/aura/camping/camping.design
 [exec] checkChanges src/aura/camping
 [exec] baseFile from after change method cFile src/aura/camping

Но файл final.txt не меняется:

build/create_changes.sh
build/create_changes.sh-meta.xml
src/aura/camping/camping.design
src/aura/camping/camping.design-meta.xml

Я заменил его прямо там CFILE="${CFILENAME/$CFILENAME/"$replace"}"

Пробовал это тоже:

if [ $(contains "${ARRAY[@]}" $(basename -- "$(dirname -- "$CFILE")")) != "y" ]
then
    CFILENAME="$CFILE"
    ARRAY+=($(basename -- "$(dirname -- "$CFILE")"))
    replace="src/aura/"$(basename -- "$(dirname -- "$CFILE")")
    #CFILE="${CFILENAME/$CFILENAME/"$replace"}"
    sed -i 's/$CFILENAME/$replace/' final.txt
else
    continue
fi

Я что-то здесь упускаю?

1 Ответ

0 голосов
/ 21 сентября 2018

Ваша попытка была успешной в большинстве случаев, но часть, касающаяся изменения содержимого файла, неверна в обеих попытках.

Problem 1

Вы были удивлены, что приведенная ниже попыткане заменил содержимое файла.Это не так.

CFILE="${CFILENAME/$CFILENAME/"$replace"}"

Потому что выше - внутренняя конструкция bash для замены строки.Он просто заменяет содержимое строки, хранящейся в переменной CFILENAME, и устанавливает результат в CFILE.Изменение файла вообще не производится.

Судя по вашим данным, ваш CFILENAME будет иметь значение src/aura/camping/camping.design, а переменная replace будет src/aura/camping.Выполнение вышеизложенного приведёт строку src/aura/camping к переменной CFILE, а , а не к файлу, указанному переменной CFILE.

Problem 2

Похоже, вы определили, что sed решит вашу проблему, которая находится на правильном пути, но вы, кажется, пропустили пару уловок.

  1. В вашей переменной sed определены переменныепоиск и замена запчастей, но проблема с кавычками.Переменные в оболочке bash не расширяются при одинарных кавычках, а только в двойных кавычках.
  2. Следующая проблема связана со строкой де-ограничителя, используемой в sed, которая по умолчанию /.Но помните, что и в исходной, и в замещающей строках присутствует /, поэтому sed не поймет, что такое исходный текст и текст замены.Вам нужно определить de-limiter, который не является /, а также любой метасимвол, который не является частью вашей строки.Я бы порекомендовал | в вашем случае

    sed "s|$CFILENAME|$replace|" final.txt
    
  3. Теперь самая большая проблема связана с флагом -i в вашей команде sed, что означает редактирование файлов на месте.в то время как.Помните, что вы читаете файл в цикле с построчным построением while read, и теперь вы редактируете этот файл после анализа каждой строки.Вы ошибаетесь с изменением направления оболочки здесь.Идеальный способ - перенаправить построчное редактирование во временный файл и переместить его в исходный файл после завершения цикла.

    sed "s|$CFILENAME|$replace|" final.txt >> temp_final.txt
    

Примерно так же, как и выше, используя >>, который добавляет к файлу.И как только цикл завершится, вернитесь к исходному файлу, используя mv

mv -- temp_final.txt final.txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...