如何在 bash 脚本中的特殊字符后添加 space?
How to add a space after special characters in bash script?
我有一个文本文件,其中包含
!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 <
我试过使用 awk split 但它没有给出预期的输出。有什么解决方法吗?通过使用 awk 或 sed。
如果文件总是在行首包含一个符号,那么使用这个
sed -Ei 's/^(.)/ /g' yourfile.txt
-E
选项是告诉sed
使用正则表达式。 -i
修改内联文件,如果你想输出到控制台或另一个文件,你可以删除它。 ^(.)
正则表达式捕获行中的第一个字符并向其添加 space (
)
假设special characters
是non-numeric和non-alphabetic字符,行中可以出现特殊字符anywhere
,用下面的正则表达式替换。
sed 's/[^a-zA-Z0-9]/& /g' urfile
以下假定您要在 !@#$%
集中的每个字符后添加一个 space(即使它是一行中的最后一个字符)。测试文件:
$ 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
with plain 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 '%s\n' "$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 '%s\n' "$line"
done < file.txt
a! a
@ bb
c# c
$ dd
ee%
foo
% b% r
您在示例中调用 special 的字符似乎是 GNU sed
中称为 [[:punct:]]
的字符的子集,因此我提出以下解决方案:
sed 's/\([[:punct:]]\)/ /g' file.txt
其中file.txt
内容为
!aa
@bb
#cc
$dd
%ee
输出
! aa
@ bb
# cc
$ dd
% ee
说明:我使用捕获组 \(
...\)
,其中包含属于 [:punct:]
的任何字符,然后我用捕获的内容替换捕获的内容,然后是 space。我使用 g
将其应用于每一行中的所有出现,尽管这对上面的数据没有明显影响。如果您确定每一行中最多有一个字符要替换,您可以选择删除 g
。
如果您想了解有关 [:punct:]
或其他类似字符集的更多信息,请阅读 Character Classes on Regular-Expressions.info
我有一个文本文件,其中包含
!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 <
我试过使用 awk split 但它没有给出预期的输出。有什么解决方法吗?通过使用 awk 或 sed。
如果文件总是在行首包含一个符号,那么使用这个
sed -Ei 's/^(.)/ /g' yourfile.txt
-E
选项是告诉sed
使用正则表达式。 -i
修改内联文件,如果你想输出到控制台或另一个文件,你可以删除它。 ^(.)
正则表达式捕获行中的第一个字符并向其添加 space (
)
假设special characters
是non-numeric和non-alphabetic字符,行中可以出现特殊字符anywhere
,用下面的正则表达式替换。
sed 's/[^a-zA-Z0-9]/& /g' urfile
以下假定您要在 !@#$%
集中的每个字符后添加一个 space(即使它是一行中的最后一个字符)。测试文件:
$ 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
with plain 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 '%s\n' "$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 '%s\n' "$line"
done < file.txt
a! a
@ bb
c# c
$ dd
ee%
foo
% b% r
您在示例中调用 special 的字符似乎是 GNU sed
中称为 [[:punct:]]
的字符的子集,因此我提出以下解决方案:
sed 's/\([[:punct:]]\)/ /g' file.txt
其中file.txt
内容为
!aa
@bb
#cc
$dd
%ee
输出
! aa
@ bb
# cc
$ dd
% ee
说明:我使用捕获组 \(
...\)
,其中包含属于 [:punct:]
的任何字符,然后我用捕获的内容替换捕获的内容,然后是 space。我使用 g
将其应用于每一行中的所有出现,尽管这对上面的数据没有明显影响。如果您确定每一行中最多有一个字符要替换,您可以选择删除 g
。
如果您想了解有关 [:punct:]
或其他类似字符集的更多信息,请阅读 Character Classes on Regular-Expressions.info