Sed 替换分组在 OSX 中附加,而不是在 Linux 中附加预期的子组

Sed 替换分组在 OSX 中附加,而不是在 Linux 中附加预期的子组

我有三个逗号分隔的列。姓氏、名字、社交名称。

我正在尝试使用大写姓氏列中的所有字符

sed 's/\([^,]*\)/\U\1/' foo.file

在 osx 中,此命令将大写 U 附加到每行的开头,而不是将姓氏列大写,但它在我的 ubuntu 实例上按预期工作。

我不明白为什么会发生这种情况。

手册页列出了一个错误“多字节字符不能用作 ''s'' 和 ''y'' 命令的分隔符。我不确定 / 是否是多字节字符(不认为它是),但如果我用“i”替换分隔符,也会发生同样的事情,所以这不是问题。

答案1

sed 'h;s/[^,]*,[^,]*,//
     y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
     H;x;s/[^,]*\n//

' foo.file

答案2

\U是一个 GNUism,实际上受到 BSDism 的启发,因为它来自编辑器s中的等效命令ex(命令行模式vi)。

OS/Xsed很可能源自 FreeBSD,而 FreeBSD 又源自 4.4BSD sed,后者是在与 AT&T 发生版权问题后从头开始重写的。无论如何,BSD 和 AT&T 都不sed支持\U他们的s命令。

要转换为大写,在sed可移植中,通常使用y命令如已经所示

但这里可能会使用更好的方法awk

awk -F, -vOFS=, '{$1 = toupper($1); print}'

答案3

简单的任务不需要sed

while IFS=',' read -r first mid last
do
    echo "$first, $mid, ${last^^}"
done < file_with_commas

如果bash版本不支持变量扩展,您可以使用tr

last=$(echo $last | tr [[:lower:]] [[:upper:]])

答案4

似乎 /U 和 /L 不适用于 OSX/BSD sed

随着

sed /pattern/,+2d # like `sed '/pattern/{N;N;d;}'`
sed -n 0~3p # like `awk NR%3==0`
sed /pattern/Q # like `awk '/pattern/{exit}1'` or `sed -n '/pattern/,$!p'`
sed 's/\b./\u&/g' # \u converts the next character to uppercase
sed 's/^./\l&/' # \l converts the next character to lowercase
sed -i '1ecat file_to_prepend' file # e executes a shell command
sed -n l0 # 0 disables wrapping

感谢你们。我的声誉还不够高,无法投票,但 Mike 你用 sed 解决了我的问题,我同意 Stephane 的观点。 awk 似乎是更好的选择。

相关内容