在unix shell脚本中用特定字符替换特定的字符模式

时间:2014-05-09 12:19:25

标签: shell unix awk grep tr

在开始时我们需要检查连字符之前是否有2个或3个字符,然后应保留为其和if 连字符前面的字符(如果有的话)是1或大于3,那么我们就可以在连字符后加上空格

输入

SB-743921- 11C

SBDF-559448-AAA

SBI-742457-A

S-SANJAY PFF

GH222016/Love

输出

SB-743921- 11C

SBDF- 559448-AAA

SBI-742457-A

S- SANJAY PFF

GH222016/Love

我正在尝试使用像

这样的tr命令
cat input.txt|tr "...?-" " "

但它正在替换所有 - 空格

3 个答案:

答案 0 :(得分:2)

试试这个:

awk -F- -v OFS="-" '{for(i=NF-1;i>=1;i--){l=length($i);if(l<2||l>3)$(i+1)=" "$(i+1)}}7' file

以上一行适用于每个 -的规则:例如:

kent$  cat f
SB-743921- 11C
SBDF-559448-AAA
SBI-742457-A
S-SANJAY PFF
GH222016/Love

kent$  awk -F- -v OFS="-" '{for(i=NF-1;i>=1;i--){l=length($i);if(l<2||l>3)$(i+1)=" "$(i+1)}}7' f
SB-743921-  11C
SBDF- 559448- AAA
SBI-742457- A
S- SANJAY PFF
GH222016/Love

如果您只想在第一个-之前检查该列,则会更容易。

仅适用于第一种情况:

 awk -F- -v OFS="-" 'NF>1{l=length($1);if(l<2||l>3)$2=" "$2}7' file

答案 1 :(得分:0)

tr tr 将一个字符与另一个字符联系起来。您可能需要使用具有更强大的正则表达式引擎的工具:

perl -pe 's/-/- /g; s/- (\w\w\w?)\b/-$1/g;' <input.txt

这会在连字符后的到处中放置一个空格,然后在你不想要的情况下删除它。

答案 2 :(得分:0)

在这种情况下,

sed可能最简单:

sed -E 's/^([^-]|[^-]{4,})-/\1- /' input.txt

总体效果是在第一个-之前的第-行之后插入空格,而第一个sed之前没有正好2或3个字符。

  • -E使用正则表达式来匹配输入行; sed(GNU -r中的别名:sed)使s/<to replace>/<with what>/支持扩展正则表达式(而不是默认的 basic
  • sed^文本替换(文本替换)命令。
  • 初始[^-]可确保匹配从每行的开头开始。
  • -表示:任何字符 a [^-]|[^-]{4,}
  • -表示:匹配 单个字符而不是| -(...)
  • 以外的四个或更多个字符
  • \1,即所谓的捕获组,会导致与所包含表达式匹配的字符串被保存(捕获)以供日后使用。
  • 替换字符串将捕获的字符串引用为\1- (所谓的反向引用,这里指的是 1st (且仅限)捕获组)。使用-作为替换字符串可以有效地在第一个sed之后添加一个空格。
  • 任何不匹配的行都会通过未经修改的传递(这是{{1}}的默认行为 - 它会打印所有输入行,无论是否修改过。)