【发布时间】:2012-09-11 03:01:47
【问题描述】:
使用awk/sed从字符串中去除第一个和最后一个字符相当容易吗?
假设我有这个字符串
( 1 2 3 4 5 6 7 )
我想去掉括号。
我应该怎么做?
【问题讨论】:
使用awk/sed从字符串中去除第一个和最后一个字符相当容易吗?
假设我有这个字符串
( 1 2 3 4 5 6 7 )
我想去掉括号。
我应该怎么做?
【问题讨论】:
sed方式
$ echo '( 1 2 3 4 5 6 7 )' | sed 's/^.\(.*\).$/\1/'
1 2 3 4 5 6 7
方法
$ echo '( 1 2 3 4 5 6 7 )' | awk '{print substr($0, 2, length($0) - 2)}'
1 2 3 4 5 6 7
POSIX 方式
$ var='( 1 2 3 4 5 6 7 )'; var="${var#?}"; var="${var%?}"; echo "$var"
1 2 3 4 5 6 7
猛击方式
$ var='( 1 2 3 4 5 6 7 )'; echo "${var:1: -1}"
1 2 3 4 5 6 7
如果您使用bash,则使用 bash 方式。
如果没有,请选择 posix-sh 方式。它比加载sed 或awk 更快。
除此之外,您还可能正在执行其他文本处理,您可以将其与此结合使用,因此根据脚本的其余部分,您最终可能会受益于sed 或awk。
为什么这不起作用?
sed '..' s_res.temp > s_res.temp?
这不起作用,因为重定向> 将在读取文件之前将其截断。
要解决这个问题,您有一些选择:
你真正想做的是编辑文件。 sed 是 流编辑器 而不是文件编辑器。ed 虽然是文件编辑器(也是标准的!)。所以,使用ed:
$ printf '%s\n' "%s/^.\(.*\).$/\1/" "." "wq" | ed s_res.temp
使用一个临时文件,然后mv它来替换旧文件。
$ sed 's/^.\(.*\).$/\1/' s_res.temp > s_res.temp.temp
$ mv s_res.temp.temp s_res.temp
使用sed 的-i 选项。这仅适用于 GNU-sed,因为 -i 不是 POSIX 和 GNU-only:
$ sed -i 's/^.\(.*\).$/\1/' s_res.temp
滥用外壳(真的不推荐):
$ (rm test; sed 's/XXX/printf/' > test) < test
在 Mac OS X(最新版本 10.12 - Sierra)上,bash 坚持使用相当旧的版本 3.2.57。始终可以使用brew 安装bash 并获得版本4.x,其中包括上述工作所需的替换。
有一个bash版本和各自变化的集合,编译在bash-hackers wiki
【讨论】:
sed。但是,有一个问题,为什么这不起作用? sed 's/^.\(.*\).$/\1/' s_res.temp > s_res.temp ?
-bash: -1: substring expression < 0。以下确实有效:var='( 1 2 3 4 5 6 7 )'; echo "${var:1: ${#var}-2}"
bash 坚持使用相当旧的版本 3.2.57。始终可以使用brew 安装bash 并获得版本4.x,其中包括上述工作所需的替换。
要从给定字符串中删除第一个和最后一个字符,我喜欢这个sed:
sed -e 's/^.//' -e 's/.$//'
# ^^ ^^
# first char last char
看一个例子:
sed -e 's/^.//' -e 's/.$//' <<< "(1 2 3 4 5 6 7)"
1 2 3 4 5 6 7
【讨论】:
还有一种perl方式:
perl -pe 's/^.|.$//g'
【讨论】:
如果我想使用 sed 删除前 (1) 个字符和后两 (2) 个字符。
输入"t2.large",
输出t2.large
sed -e 's/^.//' -e 's/..$//'
`
【讨论】: