sed不给我正确的替代操作换Mac的换行 – GNU sed和BSD / OSX sed之间的差异
我使用这个引用: sed help:匹配和replace文字“\ n”(不是换行符)
我有一个文件“test1.txt”,其中包含一个stringhello \ ngoodbye
我用这个命令search并用实际换行符replace“\ n”:
sed -i '' 's/\\n/\n/g' test1.txt 但结果是: hellongbybye 。 它只是将“\ n”replace为“n”而不是实际的新行。 这和/ t的情况一样,它会留下“t”而不是标签。
''是MAC中的未定义错误: http : //mpdaugherty.wordpress.com/2010/05/27/difference-with-sed-in-place-editing-on-mac-os-x-vs-linux /
更新 :
我已经尝试了@ hek2mgl提示的两个命令:
 sed -i 's/\\n/\n/g' test.txt # Or: sed -i'' 's/\\n/\n/g' test.txt 
虽然他们可能与Linux操作系统,MAC操作系统,我得到了以下错误:
 sed: 1: "test1.txt": undefined label 'est1.txt' 
不知道为什么我不能得到这个工作。 提前致谢。
  使用BSD / macOS sed ,要在s函数调用的replacestring中使用换行符,则必须使用\ -escaped 实际换行符 – 转义序列\n在那里不受支持(与调用的正则expression式部分不同)。 
- 
要么 :只需插入一个实际的换行符: sed -i '' 's/\\n/\ /g' test1.txt
- 
或者 :使用ANSI C引用的string( $'...')在换行符($'\n';在bash,ksh或zsh)中进行拼接:sed -i '' 's/\\n/\'$'\n''/g' test1.txt
 相比之下, GNU sed 会识别replacestring中的\n ; 请阅读这两个实现之间差异的综合概述。 
  GNU sed (Linux)与BSD / macOS sed之间的区别 
  macOS使用sed [1]的BSD版本,它在许多方面与Linux发行版附带的GNU sed版本不同。 
 它们的共同点是POSIX规定的function:请参阅POSIX sed规范。 
最便携的方法是仅使用POSIXfunction ,但限制function :
-  值得注意的是,POSIX 仅支持基本的正则expression式 ,这些基本的正则expression式有很多限制(例如,根本不支持|(变更),不支持+和?)和不同的转义要求。-  警告: GNU sed(不带-r),支持\|,\+和\?,这不符合POSIX标准; 使用--posix来禁用 (见下文)。
 
-  警告: GNU 
-   仅使用POSIXfunction :
-   (两个版本): 只使用-n和-e选项(特别是,不要使用-E或-r打开对扩展正则expression式的支持)
-   GNU sed:添加选项--posix以确保仅用于POSIXfunction(您并不严格需要此function,但如果没有它,最终可能会在不注意的情况下使用非POSIXfunction而不注意; 警告 :--posix本身 不符合POSIX )
-  使用POSIX-onlyfunction意味着更严格的格式要求(在GNU sed放弃许多便利):-  控制字符序列(如\n和\t通常不受支持。
-  标签和分支命令(如b)后面必须跟一个实际的换行符或通过一个单独的-e选项延续。
- 详情请参阅下文。
 
-  控制字符序列(如
 
-   (两个版本): 只使用
但是, 两个版本都实现了对POSIX标准的扩展 :
-   他们实现什么扩展不同 (GNU sed实现更多)。
- 即使是他们所实现的扩展在语法上也有 部分不同 。
如果您需要支持这两个平台(讨论差异):
-   不兼容的function:
-   不带参数的-i选项的使用(不带备份的就地更新)是不兼容的:-   BSD sed:必须使用-i ''
-   GNU sed:只能使用-i(相当于:-i'') – 使用-i ''不起作用。
 
-   BSD 
-   -i在GNUsed和最新版本的BSDsed(例如,在FreeBSD 10上)中明智地打开了每个input文件的行编号 ,但在10.12版本的macOS上没有 。
 请注意,如果缺less-i所有版本的数字行, 则会跨越input文件累积 。
-  如果最后一个input行没有结尾的换行符 (并被打印):
-   BSD sed: 总是在输出上附加一个换行符 ,即使input行不结束。
-   GNU sed: 保留尾随换行符状态 ,即仅当input行结束时才附加换行符。
 
-   BSD 
 
-   不带参数的
-   共同特点:
-  如果你将你的sed脚本限制在BSDsed支持的地方,他们通常也可以在GNUsed工作 – 除了在-E上使用平台特定的扩展正则expression式特性之外。 显然,你也会放弃特定于GNU版本的扩展。 请参阅下一节。
 
-  如果你将你的
由BSD版本的更严格的要求驱动的跨平台支持指南(OS X / BSD,Linux) :
  请注意,我正在分别使用BSD和GNU版本的sed使用shorthands macOS和Linux ,因为它们是每个平台上的股票版本。  但是,可以在macOS上安装GNU sed ,例如,用brew install gnu-sed使用Homebrew 。 
  注意 : 除了使用-r和-E标志 ( 扩展正则expression式)之外,以下指令等同于编写符合POSIX标准的 sed脚本。 
-  对于POSIX合规性,你必须限制自己的POSIX BREs( 基本正则expression式) ,不幸的是,顾名思义,这是非常基本的。 
 警告 :不要假设\|,\+和\?支持:虽然GNUsed支持它们(除非使用--posix),BSDsed不支持 – 这些function不符合POSIX标准。
 而\+和\?可以用 POSIX兼容的方式进行仿真 :
 \{1,\}为\+,
 \{0,1\}为\?,
 \|(替代) 不能 ,不幸的是。
- 
对于更强大的正则expression式, 使用 -E(而不是-r)来支持ERE( 扩展的正则expression式) (GNUsed不是文件-E,但是它在那里工作,作为-r的别名; 更新版本的BSDsed,比如在FreeBSD 10上,现在也支持-r,但是10.10版本的macOS版本不支持 )。
 警告 :即使使用-r/-E表示您的命令在定义上不符合POSIX,您仍然必须将自己限制为POSIX ERE(扩展正则expression式) 。 可悲的是,这意味着你将无法使用一些有用的结构,特别是:-  字边界断言,因为它们是特定于平台的 (例如,在Linux上是\<,在OS X上是[[:<]]。
-   在正则expression式中反向引用(而不是在函数调用的replacestring中对“捕获组匹配”的“后向引用”),因为BSD sed在扩展正则expression式中不支持它们(但是,奇怪的是, 基本的,POSIX授权的)。
 
-  字边界断言,因为它们是特定于平台的 (例如,在Linux上是
- 
控制字符转义序列,如 \n和\t:-  在正则expression式中 (既包括select模式,也包括s函数的第一个参数),假定只有\n被识别为一个转义序列(很less使用,因为模式空间通常是一行(不终止\n)而不是在字符类中 ,因此,例如[^\n]不起作用;(如果您的input不包含\t以外的控制字符,可以用[[:print:][:blank:]]来模拟[^\n][[:print:][:blank:]];否则,拼接控制字符为文字 [2] ) – 通常,包含控制字符作为文字 ,要么通过拼接在ANSI C引号string (例如,$'\t')支持它(bash,ksh,zsh),或者通过使用printf命令replace (例如"$(printf '\t')") 。-  仅限Linux: 
 sed 's/\t/-/' <<<$'a\tb' # -> 'a-b'
-   macOS 和 Linux: 
 sed 's/'$'\t''/-/' <<<$'a\tb' # ANSI C-quoted string
 sed 's/'"$(printf '\t')"'/-/' <<<$'a\tb' # command subst. with printf
 
-  仅限Linux: 
- 
在与 s命令一起使用的replacestring中 , 假设不支持控制字符转义序列 ,所以再次包含控制字符。 作为文字 ,如上所述。-  仅限Linux: 
 sed 's/-/\t/' <<<$'ab' # -> 'a<tab>b'
-   macOS 和 Linux: 
 sed 's/-/'$'\t''/' <<<'a-b'
 sed 's/-/'"$(printf '\t')"'/' <<<'a-b'
 
-  仅限Linux: 
- 
对于 i和a函数的文本参数同上: 不要使用控制字符序列 – 见下文。
 
-  在正则expression式中 (既包括select模式,也包括
-   标签和分支 :标签以及b和t函数的标签名称参数 后面必须紧跟一个字面换行符或一个拼接的$'\n'。 或者,使用多个-e选项并在标签名称之后立即终止。-  仅限Linux: 
 sed -n '/a/ bLBL; d; :LBL p' <<<$'a\nb' # -> 'a'
-   macOS 和 Linux:
-  无论(实际换行符): 
 sed -n '/a/ bLBL d; :LBL p' <<<$'a\nb'
-   OR(拼接$\n实例):
 sed -n '/a/ bLBL'$'\n''d; :LBL'$'\n''p' <<<$'a\nb'
-   OR(多个-e选项):
 sed -n -e '/a/ bLBL' -e 'd; :LBL' -e 'p' <<<$'a\nb'
 
-  无论(实际换行符): 
 
-  仅限Linux: 
-  函数i和a用于插入/附加文本 : 在\指定函数名称,然后按照文字换行符或拼接的$'\n'指定文本参数。-  仅限Linux: 
 sed '1 i new first line' <<<$'a\nb' # -> 'new first line<nl>a<nl>b'
-   macOS 和 Linux: 
 sed -e '1 i\'$'\n''new first line' <<<$'a\nb'
-  注意:
-  没有-e,text参数在macOS(bug?)输出中莫名其妙地不是换行符。
-   不要在文本参数中使用控制字符转义,例如\n和\t,因为它们只在Linux上受支持。
- 如果文本参数因此具有实际的内部换行符,则将其隐藏起来。
-  如果你想在文本参数之后放置额外的命令,你必须用一个(非转义的)换行符(不pipe是字面还是拼接)来终止它,或者继续单独的-e选项(这是一个适用于所有版本的一般要求) 。
 
-  没有
 
-  仅限Linux: 
-  在函数列表 ( {...}包含的多个函数调用)中, 一定要在closures}之前终止最后一个函数, 。- 仅限Linux:
-  sed -n '1 {p;q}' <<<$'a\nb' # -> 'a'
- macOS 和 Linux:
-  sed -n '1 {p;q;}' <<<$'a\nb'
 
 从BSD sed完全没有GNU sed特有的function : 
如果你需要支持这两个平台,你将错过GNUfunction:
- 
各种正则expression式匹配和replace选项 (包括线select模式和 s函数的第一个参数):-   对于不区分大小写的正则expression式匹配的I选项(令人难以置信的是,BSDsed根本不支持这一点)。
-  多行匹配的M选项(其中^/$匹配每行的开始/结尾)
-  有关特定于sfunction的其他选项,请参阅https://www.gnu.org/software/sed/manual/sed.html#The-_0022s_0022-Command
 
-   对于不区分大小写的正则expression式匹配的
- 
逃逸序列 - 
在 s///函数的replace参数中,replace相关的转义序列(如\u允许在限制范围内进行子string操作 ; 例如sed 's/^./\u&/' <<<'dog' # -> 'Dog'– 请参阅http://www.gnu.org/software/sed/manual/sed.html#The-_0022s_0022 -命令
- 
控制字符转义序列:除了 \n,\t,…,基于码点的转义; 例如,所有以下转义(hex,八进制,十进制)表示单引号('):\x27,\o047,\d039– 请参阅https://www.gnu.org/software/sed/manual/ sed.html#逃逸
 
- 
- 
地址扩展 ,比如 first~step匹配每first~step行,addr, +N匹配addrN行, – 见http://www.gnu.org/software/sed/manual/sed。; HTML#地址
  [1] macOS sed版本比其他类似BSD的系统(如FreeBSD和PC-BSD)上的版本要旧 。  不幸的是,这意味着你不能认为在FreeBSD上工作的特性,例如,在macOS上也是一样的。 
  [2] ANSI C引用的string$'\001\002\003\004\005\006\007\010\011\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\177'包含除\n (和NUL)以外的所有ASCII控制字符,因此您可以将它与[:print:]组合使用对于[^\n]非常强大的仿真: 
 '[[:print:]'$'\001\002\003\004\005\006\007\010\011\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\177''] 
这似乎有点奇怪,但请尝试:
 sed -i '' 's/\\n/\ /g' test1.txt 
 即,使用一个实际的换行符而不是\n 。 
 解释是你有一个奇怪的sed ! 有关详细信息,请参阅mac sed手册: https : //developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/sed.1.html 
 在那里的s命令的描述中,它说: 
 A line can be split by substituting a newline character into it. To specify a newline character in the replacement string, precede it with a backslash. 
 另外,在-i选项的描述中,它表示扩展名不是可选的,如果你不需要,你必须指定一个空的参数。 所以一切都最终有意义!