Using variables in sed -f (where sed script is in a file rather than inline)

前端 未结 5 1041
醉话见心
醉话见心 2021-01-13 03:01

We have a process which can use a file containing sed commands to alter piped input.

I need to replace a placeholder in the input with a variable value,

相关标签:
5条回答
  • 2021-01-13 03:38

    I am in agreement with sputnick. I don't believe that sed would be able to complete that task.

    However, you could generate that file on the fly.

    You could change the date to a fixed string, like __DAYOFWEEK__.

    Create a temp file, use sed to replace __DAYOFWEEK__ with $(date +%Y).

    Then parse your file with sed -f $TEMPFILE.

    sed is great, but it might be time to use something like perl that can generate the date on the fly.

    0 讨论(0)
  • 2021-01-13 03:39

    AFAIK, it's not possible. Your best bet will be :

    INPUT FILE

    aaa
    bbb
    ccc
    

    SH SCRIPT

    #!/bin/sh
    
    STRING="${1//\//\\/}"   # using parameter expansion to prevent / collisions
    
    shift
    
    sed "
    s/aaa/$STRING/
    " "$@"
    

    COMMAND LINE

    ./sed.sh "fo/obar" <file path>
    

    OUTPUT

    fo/obar
    bbb
    ccc
    
    0 讨论(0)
  • 2021-01-13 03:40

    As others have said, you can't use variables in a sed script, but you might be able to "fake" it using extra leading input that gets added to your hold buffer. For example:

    [ghoti@pc ~/tmp]$ cat scr.sed 
    1{;h;d;};/^--$/g
    [ghoti@pc ~/tmp]$ sed -f scr.sed <(date '+%Y-%m-%d'; printf 'foo\n--\nbar\n')
    foo
    2012-10-10
    bar
    [ghoti@pc ~/tmp]$ 
    

    In this example, I'm using process redirection to get input into sed. The "important" data is generated by printf. You could cat a file instead, or run some other program. The "variable" is produced by the date command, and becomes the first line of input to the script.

    The sed script takes the first line, puts it in sed's hold buffer, then deletes the line. Then for any subsequent line, if it matches a double dash (our "macro replacement"), it substitutes the contents of the hold buffer. And prints, because that's sed's default action.

    Hold buffers (g, G, h, H and x commands) represent "advanced" sed programming. But once you understand how they work, they open up new dimensions of sed fu.

    Note: This solution only helps you replace entire lines. Replacing substrings within lines may be possible using the hold buffer, but I can't imagine a way to do it.

    (Another note: I'm doing this in FreeBSD, which uses a different sed from what you'll find in Linux. This may work in GNU sed, or it may not; I haven't tested.)

    0 讨论(0)
  • 2021-01-13 03:56

    This might work for you (GNU sed):

    cat <<\! > replacements.sed
    /XX/{s//'"$(date +%F)"'/;s/.*/echo '&'/e}
    !
    echo "Today is XX" | sed -f replacements.sed
    

    If you don't have GNU sed, try:

    cat <<\! > replacements.sed
    /XX/{
        s//'"$(date +%F)"'/
        s/.*/echo '&'/
    }
    !
    echo "Today is XX" | sed -f replacements.sed | sh
    
    0 讨论(0)
  • 2021-01-13 04:00

    To add a newline in the replacement expression using a sed file, what finally worked for me is escaping a literal newline. Example: to append a newline after the string NewLineHere, then this worked for me:

    #! /usr/bin/sed -f
    s/NewLineHere/NewLineHere\
    /g
    

    Not sure it matters but I am on Solaris unix, so not GNU sed for sure.

    0 讨论(0)
提交回复
热议问题