You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sed处理多行文件内容变量时报错,求解决方案

How to Insert Multi-Line File Content Into a Specific JSON Position Using Sed (Without jq)

I see the issue here—when your variable $a contains newlines, embedding it directly into the sed substitution command breaks things. Sed parses commands line-by-line, so the newlines in $a split the s command into incomplete chunks, hence the "unterminated `s' command" error.

Let’s break down practical solutions to fix this, depending on whether you want to flatten the multi-line content into a single line or preserve its original line breaks:

Solution 1: Flatten Multi-Line Content Into a Single Line

If you want to merge all lines from the file into one continuous string (matching your expected output format), first strip newlines and escape characters that would break sed’s substitution logic:

# Read file, remove newlines, and escape sed special characters (&, \, /)
a=$(tr -d '\n' < file | sed -e 's/\\/\\\\/g' -e 's/\//\\\//g' -e 's/&/\\&/g')

# Use | as the sed delimiter to avoid conflicts with / in content
sed "/^[[:blank:]]*\"data_$2\": \[$/,/^[[:blank:]]*],*$/ {s|^[[:blank:]]*}$|&$a|}" "$1"

Why this works:

  • tr -d '\n' removes all newlines from the file content, ensuring $a is a single line.
  • The sed escape steps handle characters with special meaning in substitutions (backslashes, slashes, and ampersands) to prevent unexpected behavior.
  • Using | instead of / as the substitution delimiter avoids conflicts if your file content contains slashes.

Solution 2: Preserve Original Line Breaks

If you want to keep the file’s line breaks (even if it makes the JSON technically invalid), escape newlines as \n so sed interprets them correctly:

# Read entire file into one line, escape special chars, replace newlines with \n
a=$(sed -e ':a' -e 'N' -e '$!ba' -e 's/\\/\\\\/g' -e 's/\//\\\//g' -e 's/&/\\&/g' -e 's/\n/\\n/g' file)

sed "/^[[:blank:]]*\"data_$2\": \[$/,/^[[:blank:]]*],*$/ {s|^[[:blank:]]*}$|&$a|}" "$1"

How this works:

  • :a;N;$!ba is a sed trick to read the entire file into a single buffer (instead of processing line-by-line).
  • We escape special characters first, then replace each newline with \n—sed will render this as a literal newline in the output.

Solution 3: Avoid Variables Entirely (Simplest Approach)

Skip storing the file content in a variable altogether, and have sed directly read the file at the target position using the r command:

sed "/^[[:blank:]]*\"data_$2\": \[$/,/^[[:blank:]]*],*$/ {
  /^[[:blank:]]*}$/ {
    # Append file content right after the closing }
    s/^[[:blank:]]*}$/&/
    r file
  }
}" "$1"

Note:

This inserts the file content on a new line after the }. If you need it on the same line as the }, stick with Solutions 1 or 2.

Testing With Your Example

For a file with content:

yeah
is
test
my
script

Solution 1 will produce exactly your expected output:

{ "mytable_test": [ { "test1": "abc", "test2": "def", "test2": "ghi" }yeah is test my script ], "mytable": [ "test1", "test2", "test3" ] }

内容的提问来源于stack exchange,提问作者Mathie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:48:03