【问题标题】:Bash sed command gives me "invalid command code ."Bash sed 命令给了我“无效的命令代码”。
【发布时间】:2021-12-25 00:01:52
【问题描述】:

我正在尝试通过将 .js 块替换为我的 main.config.php 文件中的特定行来自动化构建过程。当我运行以下代码时:

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"

我收到此消息,但文件尚未更新/编辑:

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

我无法在搜索中找到与此特定消息相关的任何内容。有谁知道我需要更改/尝试替换我的 .php 文件中的特定行吗?

更新的脚本包含相同的消息:

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"

例如$line:

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

例如$newline:

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

更新的脚本包含@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"

【问题讨论】:

  • while 之前添加set -xv(启用调试模式),运行您的脚本,查看(调试)输出以查看sed 命令在变量展开后的样子;我猜一个变量包含一个文件路径(包括正斜杠),这将与您使用正斜杠作为 sed 脚本分隔符发生冲突
  • 请阅读您应用的标签的描述。另外,创建一个minimal reproducible example。特别是,我想知道这是否与 PHP 有任何关系,除了它应用于 PHP 文件。此外,sed 是一个程序,而不是 Bash 内置的或特定于 Bash 的命令。
  • 添加到 Ulrich 的评论...看看 sed 是如何生成错误消息的...也许添加 sed 作为标签?
  • 这是在什么平台上运行的(因此这是sed 的哪个版本)?不同版本的sedconfusingly different syntax for the -i option。此外,有几个变量引用应该用双引号引起来(shellcheck.net 将指出其中的大部分),在sed 命令need to be escaped 中执行这些字符串,你确定./ 指的是你的目录吗?期待?
  • 您使用 / 作为 sed 的 s 命令的分隔符,但变量内容包含斜杠。为s 使用不同的分隔符。

标签: bash shell sed


【解决方案1】:

使用seds 命令来替换如此复杂的行是一个失败的提议,因为您选择的任何分隔符都可能出现在行中并搞砸了。如果这些实际上是整行,最好删除它们并插入一个新的:

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

它的作用是搜索与$line 完全匹配的行的行号,然后提取行号部分。 fgrep 是必需的,否则文件中的符号将被解释为正则表达式。如果匹配,则运行sed,追加新行(a)并删除旧行(d)。

【讨论】:

  • 我将此添加到我的代码中(请参阅上面的更新代码),虽然我没有收到“无效的命令代码”,但它不会更新我的 .php 文件中的行。跨度>
  • 我试了echo $linenum,没有任何东西输出到终端。
  • 您的意思是在grep 执行后立即在脚本中回显它?这意味着输入行与配置文件中的任何行都不完全匹配。这是预期的吗?
  • 另外,您的${newline} 行需要完全向左对齐(前面没有空格,不缩进),否则空格将出现在您的输出中。
  • 是的,我在定义它的正下方的行上运行了echo $linenum,并且没有打印任何内容,是的,总会有匹配的行符合js_string 文件中的.php 条件.
猜你喜欢
  • 1970-01-01
  • 2015-05-18
  • 2020-07-30
  • 2019-04-08
  • 1970-01-01
  • 1970-01-01
  • 2011-04-28
  • 2018-12-15
  • 1970-01-01
相关资源
最近更新 更多