【问题标题】:Not able to replace String from file while iterating迭代时无法从文件中替换字符串
【发布时间】:2019-02-23 03:40:03
【问题描述】:

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

我在这里还遗漏了什么吗?

【问题讨论】:

  • 您是否要更改final.txt 的内容?或者您是否尝试更改final.txt 中列出的文件的内容?如果是前者,请显示final.txt的'before'和'after'内容;在您帖子的开头,您提到想用src/aura/camping 替换/aura/ ...但是该字符串已经在final.txt ...您真的想将src/aura/camping/camping.design 更改为srcsrc/aura/campingcamping/camping.design(注意双srccamping 字符串)

标签: bash shell replace


【解决方案1】:

您的尝试大部分都很好,但涉及更改文件内容的部分在两次尝试中都不正确。

Problem 1

您对以下尝试没有替换文件的内容感到惊讶。不会的。

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

因为上面是用于字符串替换的bash 内部构造。它只是替换存储在变量CFILENAME 中的字符串内容并将结果放入CFILE。根本没有进行任何文件修改。

根据您的输入判断,您的CFILENAME 输入将是src/aura/camping/camping.designreplace 变量将是src/aura/camping。执行上述操作会将字符串 src/aura/camping 放到变量 CFILE 中,not 放到变量 CFILE 指向的文件中。

Problem 2

您似乎已经确定sed 可以解决您的问题,这是在正确的轨道上,但您似乎错过了一些技巧。

  1. 您在sed 搜索和替换部件中定义了变量,但问题在于引号。 bash shell 中的变量在单引号时不会扩展,而只有在双引号时才会扩展。
  2. 下一个问题是sed 中使用的分隔符字符串,默认为/。但请记住,您的源字符串和替换字符串都存在 /,因此 sed 不会理解原始文本和替换文本是什么。您需要定义一个不是/ 的分隔符以及任何不属于您的字符串的元字符。在你的情况下,我会推荐|

    sed "s|$CFILENAME|$replace|" final.txt
    
  3. 现在最大的问题是你的sed 命令中的-i 标志,这意味着在原地编辑你的文件。请记住,您正在使用 while read 逐行构造循环读取文件,现在您在解析每一行后编辑此文件。您在这里以错误的方式弄乱了 shell 重定向。理想的方法是将逐行编辑重定向到临时文件,并在循环完成后将其移动到原始文件。

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

使用&gt;&gt; 附加到文件的类似上面的东西。循环结束后,使用mv恢复到原始文件

mv -- temp_final.txt final.txt

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-03
    • 2017-07-03
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多