linux下的a库在mac下用吗,macos - 在Mac(BSD)和Linux上都可以使用的sed就地标志

macos - 在Mac(BSD)和Linux上都可以使用的sed就地标志

是否有sed todo就地编辑的调用,没有可在Linux和Mac上运行的备份? 虽然OS X附带的BSD sed似乎需要sed -i '' …,但GNU sed Linux发行版通常会将引号解释为空输入文件名(而不是备份扩展名),而需要sed -i …。

是否有任何命令行语法适用于这两种风格,所以我可以在两个系统上使用相同的脚本?

13个解决方案

140 votes

如果您真的想以“简单”的方式使用.bak,以下内容适用于GNU和BSD / Mac sed:

sed -i.bak 's/foo/bar/' filename

注意缺少空间和点。

证明:

# GNU sed

% sed --version | head -1

GNU sed version 4.2.1

% echo 'foo' > file

% sed -i.bak 's/foo/bar/' ./file

% ls

file file.bak

% cat ./file

bar

# BSD sed

% sed --version 2>&1 | head -1

sed: illegal option -- -

% echo 'foo' > file

% sed -i.bak 's/foo/bar/' ./file

% ls

file file.bak

% cat ./file

bar

显然你可以删除.bak文件。

kine answered 2019-04-17T13:27:08Z

93 votes

这适用于GNU sed,但不适用于OS X:

sed -i -e 's/foo/bar/' target.file

sed -i'' -e 's/foo/bar/' target.file

这适用于OS X,但不适用于GNU sed:

sed -i '' -e 's/foo/bar/' target.file

在OS X上你

因为备份文件的扩展名将设置为-i

不能使用sed -i'' -e出于同样的原因 - 它需要-i和''之间的空格。

klickverbot answered 2019-04-17T13:28:07Z

37 votes

在OSX上,我总是通过Homebrew安装GNU sed版本,以避免脚本中的问题,因为大多数脚本都是为GNU sed版本编写的。

brew install gnu-sed --with-default-names

然后你的BSD sed将被GNU sed取代。

或者,您可以在没有默认名称的情况下安装,但随后:

安装gnu-sed后,按照说明更改PATH

检查脚本以根据您的系统在gsed和sed之间进行选择

Lewy answered 2019-04-17T13:29:07Z

17 votes

没有办法使它工作。

一种方法是使用临时文件,如:

TMP_FILE=`mktemp /tmp/config.XXXXXXXXXX`

sed -e "s/abc/def/" some/file > $TMP_FILE

mv $TMP_FILE some/file

这适用于两者

analogue answered 2019-04-17T13:29:55Z

12 votes

答:没有。

最初接受的答案实际上并不符合要求(如评论中所述)。 (当我找到sed在我的目录中“随机”出现的原因时,我找到了这个答案。)

显然没有办法让sed在MacOS和Linuces上一致地工作。

我的建议,值得一提的是,不要使用sed(具有复杂的故障模式)进行现场更新,而是生成新文件并在之后重命名。 换句话说:避免-i。

Steve Powell answered 2019-04-17T13:30:57Z

11 votes

正如Noufal Ibrahim所问,你为什么不能使用Perl? 任何Mac都有Perl,并且很少有Linux或BSD发行版在基本系统中不包含某些版本的Perl。 可能实际上缺少Perl的唯一环境之一是BusyBox(其工作方式类似于GNU / Linux for -i,但不能指定备份扩展名)。

正如ismail建议的那样,

由于perl可以在任何地方使用,我只需要sed -i

这似乎是一个比脚本,别名或其他变通方法更好的解决方案来处理GNU / Linux和BSD / Mac之间sed -i的基本不兼容性。

Alex Dupuy answered 2019-04-17T13:31:57Z

6 votes

史蒂夫鲍威尔的回答非常正确,在OSX和Linux(Ubuntu 12.04)上查阅MAN页面上的sed强调了两个操作系统中“就地”sed使用的兼容性。

JFYI,使用Linux版本的sed,-i和任何引号(表示空文件扩展名)之间应该没有空格,因此

sed Linux Man Page

#Linux

sed -i""

sed OSX手册页

#OSX (notice the space after the '-i' argument)

sed -i ""

我在一个脚本中使用别名命令和bash'if'中的'uname'的OS名称输出。 在解释引号时,试图在变量中存储依赖于操作系统的命令字符串。 为了扩展/使用脚本中定义的别名,必须使用'shopt -s expand_aliases'。 shopt的用法在这里处理。

Big Rich answered 2019-04-17T13:33:13Z

6 votes

-i选项不是POSIX Sed的一部分。 一种更便携的方法在Ex模式下使用Vim:

ex -sc '%s/alfa/bravo/|x' file

x选择所有行

x替换

x保存并关闭

Steven Penny answered 2019-04-17T13:34:14Z

3 votes

我遇到了这个问题。 唯一的快速解决方案是将mac中的sed替换为gnu版本:

brew install gnu-sed

vikrantt answered 2019-04-17T13:34:49Z

1 votes

以下适用于Linux和OS X:

aaaccaaca

例如 对于2306848386471232512文件包含-i

aaaccaaca

Linux和Mac上的收益率为aaaccaaca。 请注意,有一个带引号的字符串,其中包含空格,-i和字符串之间没有空格。 单引号或双引号都有效。

在Linux上,我在Ubuntu 14.04.4下使用bash版本4.3.11,在OS X 10.11.4 El Capitan(Darwin 15.4.0)下使用Mac版本3.2.57。

David G answered 2019-04-17T13:36:01Z

1 votes

如果您需要在bash脚本中就地执行sed,并且您不希望就地生成.bkp文件,并且您有办法检测操作系统(例如,使用ostype.sh), - 那么以下hack与bash shell内置的eval应该可以正常工作:

OSTYPE="$(bash ostype.sh)"

cat > myfile.txt <

1111

2222

EOF

if [ "$OSTYPE" == "osx" ]; then

ISED='-i ""'

else # $OSTYPE == linux64

ISED='-i""'

fi

eval sed $ISED 's/2222/bbbb/g' myfile.txt

ls

# GNU and OSX: still only myfile.txt there

cat myfile.txt

# GNU and OSX: both print:

# 1111

# bbbb

# NOTE:

# if you just use `sed $ISED 's/2222/bbbb/g' myfile.txt` without `eval`,

# then you will get a backup file with quotations in the file name,

# - that is, `myfile.txt""`

sdaau answered 2019-04-17T13:36:37Z

1 votes

这是另一个适用于Linux和macOS的版本,无需使用eval,也无需删除备份文件。 它使用Bash阵列存储sed参数,比使用eval更清晰:

# Default case for Linux sed, just use "-i"

sedi=(-i)

case "$(uname)" in

# For macOS, use two parameters

Darwin*) sedi=(-i "")

esac

# Expand the parameters in the actual call to "sed"

sed "${sedi[@]}" -e 's/foo/bar/' target.file

这不会创建备份文件,也不会创建带有附加引号的文件。

nwinkler answered 2019-04-17T13:37:22Z

0 votes

你可以用海绵。 Sponge是一个旧的unix程序,可以在moreutils包中找到(在ubuntu和debian中都可以,在mac中自制)。

它将缓冲管道中的所有内容,等待管道关闭(可能意味着输入文件已经关闭),然后覆盖:

从手册页:

概要

sed'...'文件| grep'...'| 海绵文件

Guillermo answered 2019-04-17T13:38:21Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值