每次在Unix中有两个空格的空间时,我都会尝试替换。我们只是从标准输入读取并写入标准输出。我还必须避免使用函数awk和perl。例如,如果我读到类似San Diego
的内容,则应该打印San Diego
。如果已经有多个空格,那就应该让它们独自存在。
答案 0 :(得分:1)
仅限bash怎么样?首先测试file
:
$ cat file
1
2 3
4 5
San Diego NO
然后:
$ cat file |
while IFS= read line
do
while [[ "$line" =~ (^|.+[^ ])\ ([^ ].*) ]]
do
line="${BASH_REMATCH[1]} ${BASH_REMATCH[2]}"
done
echo "$line"
done
1
2 3
4 5
San Diego NO
答案 1 :(得分:1)
你必须要小心,不要忘记开头或结尾的空格。 我提出了三个用于教育目的的解决方案:
sed 's/\(^\|[^ ]\) \($\|[^ ]\)/\1 \2/g' # solution 1
sed 's/\( \+\)/ \1/g;s/ \( \+\)/\1/g' # solution 2
sed 's/ \( \+\)/\1/g;s/\( \+\)/ \1/g' # solution 3
所有三种解决方案都使用子表达式:
<强> 9.3.6 BREs Matching Multiple Characters 强>
子表达式可以通过将其包含在BRE中来定义 字符对
\(
和\)
。这样的子表达式应该匹配 没有\(
和\)
的任何匹配,除此之外 在子表达式内锚定是可选行为;见BRE Expression Anchoring。 Subexpressions可以任意嵌套。反向引用表达式
'\n'
应匹配相同(可能 空的)字符串,由附带的子表达式匹配 在\(
之前的“\)
”和“'\n'
”之间。角色n
应为a 从1
到9
的数字,指定第n个子表达式(表示第n个子表达式) 从模式开始的第n\(
开始并结束 与相应的配对\)
)。如果表达式无效 在n
之前小于\n
个子表达式。例如, 表达式“.∗\1$
”匹配由两个相邻的行组成的行 同一个字符串的出现,表达式a*\1
失败 匹配a
。当引用的子表达式匹配多个时 string,后引用的表达式应引用最后匹配的表达式 串。如果反向引用引用的子表达式匹配 由于星号(*
)或间隔而导致多个字符串 表达式(见第(5)项),后引用应与最后一个匹配 (最右边)这些字符串。
解决方案1:sed 's/\(^\|[^ ]\) \($\|[^ ]\)/\1 \2/g'
这里有两个子表达式。第一个子表达式\(^\|[^ ]\)
匹配行的开头(^
)或(\|
)非空格字符([^ ]
)。第二个子表达式\($\|[^ ]\)
类似,但行尾($
)。
解决方案2:sed 's/\( \+\)/ \1/g;s/ \( \+\)/\1/g'
用一定数量的空格和一个空格替换一个或多个空格。然后我们通过从那些空间中移除一个空格来校正具有3个或更多空格的那些。
解决方案3:sed 's/ \( \+\)/\1/g;s/\( \+\)/ \1/g'
这与解决方案2完全相同,但反转了逻辑。首先从具有多个空格的所有序列中删除空格,然后添加空格。这个单行只比解决方案2短一个字符。
示例:基于解决方案1
以下命令不仅仅是echo "string" | sed ...
,而是显示空格,包含在printf
语句中。
# default string
$ printf "|%s|" " foo bar car "
| foo bar car |
# spaces replaced
$ printf "|%s|" "$(echo " foo bar car " | sed 's/\(^\|[^ ]\) \($\|[^ ]\)/\1 \2/g')"
| foo bar car |
# 3 spaces in front and back
$ printf "|%s|" "$(echo " foo bar car " | sed 's/\(^\|[^ ]\) \($\|[^ ]\)/\1 \2/g')"
| foo bar car |
注意:如果您想用相同的双色空格替换任何形式的空白(任何编码中的空格和制表符),您可以使用:
sed 's/\(^\|[^[:blank:]]\)\([[:blank:]]\)\($\|[^[:blank:]]\)/\1\2\2\3/g'
sed 's/\(^\|[[:graph:]]\)\([[:blank:]]\)\($\|[[:graph:]]\)/\1\2\2\3/g
答案 2 :(得分:0)
的内容
cat input.txt | sed 's,\([[:alnum:]]\) \([[:alnum:]]\),\1 \2,'
应该为此目的而工作。
答案 3 :(得分:0)
`sed 's/\([^ ]\) \([^ ]\)/\1 \2/g' file`
1)
[^ ]
- 不是空格字符
2)
\1 \2
- 在括号中找到的第一个表达式,2个空格,第二个括号到期
3)
一起使用的 s///g
sed将第一个//
中的正则表达式替换为第二个//
中的值