如何在bash脚本中的特殊字符后添加空格



我有一个文本文件,里面有

!aa
@bb
#cc
$dd
%ee

预期输出为

! aa
@ bb
# cc
$ dd
% ee

我所尝试的,echo "${foo//@/@ }"

这对一个字符串确实很有效,但对文件中的所有行都不起作用。我曾尝试使用while循环读取文件的所有行,并使用echo进行同样的操作,但它不起作用。

while IFS= read -r line; do
foo=$line
sep="!@#$%"
echo "${foo//$sep/$sep }"
done < $1

我尝试过awk分割,但它没有给出预期的输出。对此有什么变通办法吗?通过使用awk或sed。

以下假设您希望在!@#$%集中的每个字符后面添加一个空格(即使它是一行中的最后一个字符(。测试文件:

$ cat file.txt
a!a
@bb
c#c
$dd
ee%
foo
%b%r
$ sep='!@#$%'

sed:

$ sed 's/['"$sep"']/& /g' file.txt
a! a
@ bb
c# c
$ dd
ee% 
foo
% b% r

awk:

$ awk '{gsub(/['"$sep"']/,"& "); print}' file.txt
a! a
@ bb
c# c
$ dd
ee% 
foo
% b% r

使用普通bash(不推荐,速度太慢(:

$ while IFS= read -r line; do
str=""
for (( i=0; i<${#line}; i++ )); do
char="${line:i:1}"      
str="$str$char"
[[ "$char" =~ [$sep] ]] && str="$str "
done
printf '%sn' "$str"
done < file.txt
a! a
@ bb
c# c
$ dd
ee% 
foo
% b% r

或者(不确定哪一个是最糟糕的(:

$ while IFS= read -r line; do
for (( i=0; i<${#sep}; i++ )); do
char="${sep:i:1}"
line="${line//$char/$char }"
done
printf '%sn' "$line"
done < file.txt
a! a
@ bb
c# c
$ dd
ee% 
foo
% b% r

您在示例中称为特殊的字符似乎是GNUsed[[:punct:]]字符的子集,因此我提出以下解决方案:

sed 's/([[:punct:]])/1 /g' file.txt

其中CCD_ 8内容为

!aa
@bb
#cc
$dd
%ee

输出

! aa
@ bb
# cc
$ dd
% ee

说明:我使用(捕捉组。。。具有属于[:punct:]的任何字符的),然后我用该捕获的内容和空格替换所捕获的内容。我使用g将其应用于每行中的所有出现,尽管这对上面的数据没有明显的影响。如果您确定每行最多有一个字符要替换,则可以选择删除g

如果您想了解更多关于[:punct:]或其他类似字符集的信息,请阅读Regular-Expressions.info 上的字符类

如果文件总是在这样的行的开头包含一个符号,那么使用这个

sed -Ei 's/^(.)/1 /g' yourfile.txt

-E选项是告诉sed使用regex。-i以内联方式修改文件,如果您想输出到控制台或其他文件,可以将其删除。^(.)正则表达式捕获行上的第一个字符,并为其添加一个空格(1(

假设special characters是非数字和非字母字符,并且行中可以出现特殊字符anywhere,请使用以下正则表达式替换它们。

sed 's/[^a-zA-Z0-9]/& /g' urfile

最新更新