sed command with -i option failing on Mac, but works on Linux

前端 未结 12 1870
情歌与酒
情歌与酒 2020-11-22 05:04

I\'ve successfully used the following sed command to search/replace text in Linux:

sed -i \'s/old_link/new_link/g\' *

However,

相关标签:
12条回答
  • 2020-11-22 05:45

    Your Mac does indeed run a BASH shell, but this is more a question of which implementation of sed you are dealing with. On a Mac sed comes from BSD and is subtly different from the sed you might find on a typical Linux box. I suggest you man sed.

    0 讨论(0)
  • 2020-11-22 05:52

    As the other answers indicate, there is not a way to use sed portably across OS X and Linux without making backup files. So, I instead used this Ruby one-liner to do so:

    ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml
    

    In my case, I needed to call it from a rake task (i.e., inside a Ruby script), so I used this additional level of quoting:

    sh %q{ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml}
    
    0 讨论(0)
  • 2020-11-22 05:54

    Or, you can install the GNU version of sed in your Mac, called gsed, and use it using the standard Linux syntax.

    For that, install gsed using ports (if you don't have it, get it at http://www.macports.org/) by running sudo port install gsed. Then, you can run sed -i 's/old_link/new_link/g' *

    0 讨论(0)
  • 2020-11-22 05:55

    Here is an option in bash scripts:

    #!/bin/bash
    
    GO_OS=${GO_OS:-"linux"}
    
    function detect_os {
        # Detect the OS name
        case "$(uname -s)" in
          Darwin)
            host_os=darwin
            ;;
          Linux)
            host_os=linux
            ;;
          *)
            echo "Unsupported host OS. Must be Linux or Mac OS X." >&2
            exit 1
            ;;
        esac
    
       GO_OS="${host_os}"
    }
    
    detect_os
    
    if [ "${GO_OS}" == "darwin" ]; then
        sed -i '' -e ...
    else
        sed -i -e ...
    fi
    
    0 讨论(0)
  • 2020-11-22 06:01

    This works with both GNU and BSD versions of sed:

    sed -i'' -e 's/old_link/new_link/g' *
    

    or with backup:

    sed -i'.bak' -e 's/old_link/new_link/g' *
    

    Note missing space after -i option! (Necessary for GNU sed)

    0 讨论(0)
  • 2020-11-22 06:02

    I've created a function to handle sed difference between MacOS (tested on MacOS 10.12) and other OS:

    OS=`uname`
    # $(replace_in_file pattern file)
    function replace_in_file() {
        if [ "$OS" = 'Darwin' ]; then
            # for MacOS
            sed -i '' -e "$1" "$2"
        else
            # for Linux and Windows
            sed -i'' -e "$1" "$2"
        fi
    }
    

    Usage:

    $(replace_in_file 's,MASTER_HOST.*,MASTER_HOST='"$MASTER_IP"',' "./mysql/.env")
    

    Where:

    , is a delimeter

    's,MASTER_HOST.*,MASTER_HOST='"$MASTER_IP"',' is pattern

    "./mysql/.env" is path to file

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