Home > Blockchain >  Bash sed command gives me "invalid command code ."
Bash sed command gives me "invalid command code ."

Time:11-13

I'm trying to automate a build process by replacing .js chunks for particular lines in my main.config.php file. When I run the following code:

declare -a js_strings=("footer." "footerJQuery." "headerCSS." "headerJQuery.")

build_path="./build/build"
config_path="./system/Config/main.config.php"
while read -r line;
do
    for js_string in ${js_strings[@]}
    do
        if [[ $line == *$js_string* ]]
        then
            for js_file in "$build_path"/*
            do
                result="${js_file//[^.]}"
                if [[ $js_file == *$js_string* ]] && [[ ${#result} -eq 3 ]]
                then
                    sed -i "s/$line/$line$(basename $js_file)\";/g" $config_path
                fi
            done        
        fi
    done
done < "$config_path"

I get this message back, and file has not been updated/edited:

sed: 1: "./system/Config/main.co ...": invalid command code .

I haven't been able to find anything in my searches that pertain to this specific message. Does anyone know what I need to change/try to get the specific lines replaced in my .php file?

Updated script with same message:

declare -a js_strings=("footer." "footerJQuery." "headerCSS." "headerJQuery.")

build_path="./build/build"
config_path="./system/Config/main.config.php"

while read -r line;
do
    for js_string in ${js_strings[@]}
    do
        if [[ $line == *$js_string* ]]
        then
            for js_file in "$build_path"/*
            do
                result="${js_file//[^.]}"
                if [[ $js_file == *$js_string* ]] && [[ ${#result} -eq 3 ]]
                then
                    filename=$(basename $js_file)
                    newline="${line//$js_string*/$filename\";}"

                    echo $line
                    echo $newline
                    sed -i "s\\$line\\$newline\\g" $config_path
                    echo ""
                fi
            done        
        fi
    done
done < "$config_path"

Example $line:

$config['public_build_header_css_url'] = "http://localhost:8080/build/headerCSS.js";

Example $newline:

$config['public_build_header_css_url'] = "http://localhost:8080/build/headerCSS.7529a73071877d127676.js";

Updated script with changes suggested by @Vercingatorix:

declare -a js_strings=("footer." "footerJQuery." "headerCSS." "headerJQuery.")

build_path="./build/build"
config_path="./system/Config/main.config.php"

while read -r line;
do
    for js_string in ${js_strings[@]}
    do
        if [[ $line == *$js_string* ]]
        then
            for js_file in "$build_path"/*
            do
                result="${js_file//[^.]}"
                if [[ $js_file == *$js_string* ]] && [[ ${#result} -eq 3 ]]
                then
                    filename=$(basename $js_file)
                    newline="${line//$js_string*/$filename\";}"

                    echo $line
                    echo $newline
                    linenum=$(grep -n "^${line}\$" ${config_path} | cut -d':' -f 1 )
                    echo $linenum
                    [[ -n "${linenum}" ]] && sed -i "${linenum}a\\
${newline}
                    ;${linenum}d" ${config_path}
                    echo ""

                fi
            done        
        fi
    done
done < "$config_path"

CodePudding user response:

Using sed's s command to replace a line of that complexity is a losing proposition, because whatever delimiter you choose may appear in the line and mess things up. If these are in fact entire lines, it is better to delete them and insert a new one:

                linenum=$(fgrep -nx -f "${line}" "${config_path}" | awk -F : "{print \$1}" )
                [[ -n "${linenum}" ]] && sed -i "" "${linenum}a\\
${newline}
;${linenum}d" "${config_path}"

What this does is search for the line number of the line that matches $line in its entirety, then extracts the line number portion. fgrep is necessary otherwise the symbols in your file are interpreted as regular expressions. If there was a match, then it runs sed, appending the new line (a) and deleting the old one (d).

  • Related