如何在bash中单词的每五个字符后添加连字符

时间:2018-09-17 17:10:53

标签: bash awk sed

给出"ABCDEFGHIJKLMOPQRSTUVWXY"

如何实现这一结果? "ABCDE-FGHIJ-KLMNO-PQRST-UVWXY"

7 个答案:

答案 0 :(得分:8)

使用sed,您可以先在每5个字符后添加一个-,然后在行尾删除结尾的-,以实现此目的:

$ sed -E 's/.{5}/&-/g; s/-$//' <<<"ABCDEFGHIJKLMNOPQRSTUVWXY"
ABCDE-FGHIJ-KLMNO-PQRST-UVWXY

在扩展(-E)模式下:

  • .{5}匹配任意5个字符
  • &-替换为整个匹配项(5个字符)加-

然后第二个替换命令在行(-)的末尾与$匹配,并且不作任何替换。


对于GNU awk,一种选择是使用FPAT定义将行解释为一系列字段的方式,然后在每个字段之间添加-

$ awk -v FPAT='.{5}' -v OFS='-' '{ $1 = $1 } 1' <<<"ABCDEFGHIJKLMNOPQRSTUVWXY"
ABCDE-FGHIJ-KLMNO-PQRST-UVWXY

字段模式FPAT被定义为任意5个字符,而输出字段分隔符OFS被定义为-$1 = $1“触碰”每一行,使其重新格式化(没有这部分,将不会发生任何事情)。 1是导致每行打印的最短 true 条件。


在bash中执行此操作也不太困难:

#!/bin/bash

input="ABCDEFGHIJKLMNOPQRSTUVWXY"
parts=()
# build an array from slices of length 5
for (( i = 0; i < ${#input}; i += 5 )) do
  parts+=( "${input:i:5}" )
done

# join the array on IFS (use a subshell to avoid modifying IFS for rest of script)
( IFS=-; echo "${parts[*]}" )

答案 1 :(得分:1)

请您尝试以下。

echo "ABCDEFGHIJKLMOPQRSTUVWXY" | sed 's/...../&-/g;s/-$//'

答案 2 :(得分:0)

仅字母的简单解决方案是

sed -E 's/[A-Z]{4}./&-/g' file.txt

输出将是:

ABCDE-FGHIJ-KLMOP-QRSTU-VWXY

如果您希望它们包含的字符不止大写字母,请执行以下操作:

sed -E 's/[A-Za-z]{4}./&-/g' file.txt

答案 3 :(得分:0)

尝试一下

#!/bin/bash

s="ABCDEFGHIJKLMNOPQRSTUVWXY"
a=($(echo ${s} | grep -o .))

o=""
i=0
while [[ ${i} -lt ${#a[@]} ]]; do
    o="${o}${a[${i}]}"
    (( i++ ))
    [[ $(( i % 5 )) -eq 0 ]] && [[ ${i} -ne ${#a[@]} ]] && o="${o}-"
done
echo ${o}

exit 0

答案 4 :(得分:0)

使用fold/paste

的另一种解决方案
$ echo {A..Y} | tr -d ' ' |    # this is to generate the string
  fold -w5 | paste -sd-

ABCDE-FGHIJ-KLMNO-PQRST-UVWXY

答案 5 :(得分:0)

这可能对您有用(GNU sed):

sed 's/.\{5\}\B/&-/g' file

每五个字符插入一个连字符,只要第五个字符在单词中即可。

答案 6 :(得分:0)

另一个选择

perl -pe 's/(.{5})(?=.)/$1-/g' file

匹配5个字符,然后再跟另一个字符(以避免尾随的连字符问题)