Why does my variable set in a do loop disappear? (unix shell)

后端 未结 2 1190
清歌不尽
清歌不尽 2021-01-24 10:39

This part of my script is comparing each line of a file to find a preset string. If the string does NOT exist as a line in the file, it should append it to the end of the file.<

2条回答
  •  情书的邮戳
    2021-01-24 11:19

    Using shell

    If we want to make just the minimal change to your code to get it working, all we need to do is switch the input redirection:

    string=foobar
    while read line
    do
        if [ "$string" == "$line" ]; then
            islineinfile="yes"
        fi
    done <"$file"
    if [ ! "$islineinfile" == yes ]; then
        echo "$string" >> "$file"
    fi
    

    In the above, we changed cat "$file" | while do ...done to while do...done<"$file". With this one change, the while loop is no longer in a subshell and, consequently, shell variables created in the loop live on after the loop completes.

    Using sed

    I believe that the whole of your script can be replaced with:

    sed -i.bak '/^foobar$/H; ${x;s/././;x;t; s/$/\nfoobar/}' file*
    

    The above adds line foobar to the end of each file that doesn't already have a line that matches ^foobar$.

    The above shows file* as the final argument to sed. This will apply the change to all files matching the glob. You could list specific files individually if you prefer.

    The above was tested on GNU sed (linux). Minor modifications may be needed for BSD/OSX sed.

    Using GNU awk (gawk)

    awk -i inplace -v s="foobar" '$0==s{f=1} {print} ENDFILE{if (f==0) print s; f=0}' file*
    

    Like the sed command, this can tackle multiple files all in one command.

提交回复
热议问题