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

如何用sed或awk在多行正则匹配前插入文本?

Cleaner Alternatives for Inserting Text Before a Target Key and Preceding Comments

Great question! Your current sed+tr approach works, but we can definitely make this more maintainable with simpler sed syntax or a clean awk implementation. Let's break down both options:

1. GNU Sed (No tr Required)

GNU sed has a handy -z flag that reads the entire file as a single stream (using null characters as separators instead of newlines), letting us directly match multi-line patterns without converting newlines. This eliminates the need for tr entirely:

# Define the text to insert
insert_text='# 1x
# 2x
"keyx": null,
'
# Target key to match
target_key='key2'

# Run sed with multi-line support
sed -z "s/\(\(\s*#.*\n\)*\)\(\s*\"$target_key\":\)/$insert_text\1\3/" test.txt

How it works:

  • The -z flag treats newlines as regular characters, so we can match the sequence of preceding comments with (\s*#.*\n)* (any number of lines starting with optional whitespace and a #).
  • The regex captures those comments and the target key line, then replaces them with your insertion text, followed by the captured comments and key line.

2. Concise Awk Implementation

Awk’s line-by-line processing and variable tracking make this task extremely readable and easy to maintain. Here’s a straightforward script:

# Define the text to insert
insert_text='# 1x
# 2x
"keyx": null,
'
# Target key to match
target_key='key2'

awk -v insert="$insert_text" -v key="$target_key" '
    # Collect all preceding comment lines
    /^\s*#/ {
        comments = comments $0 "\n"
        next
    }
    # When we hit the target key line
    /^\s*\"'"$key"'\":/ {
        print insert comments $0
        comments = ""
        next
    }
    # For all other lines, print accumulated comments + current line
    {
        print comments $0
        comments = ""
    }
    # Print any remaining comments at the end of the file
    END { print comments }
' test.txt

How it works:

  • We use a comments variable to accumulate any lines that start with optional whitespace and a #.
  • When we encounter the target key line, we first print your insertion text, then the accumulated comments, then the key line itself.
  • For all other lines, we print any accumulated comments followed by the current line, then reset the comments variable.
  • The END block ensures we don’t miss any trailing comments in the file.

Both of these approaches will produce your desired output, and they’re far easier to read, edit, and maintain than the original sed+tr method.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:00:06