shell - 用递增值替换字符串

时间:2017-03-02 11:48:55

标签: shell awk

我有这个字符串:

"a | a | a | a | a | a | a | a"

我希望用增量值替换每个“|”,如下所示:

"a0a1a2a3a4a5a6a"

我知道我可以使用gsub来替换字符串:

> echo "a | a | a | a | a | a | a | a" | awk '{gsub(/\ \|\ /, ++i)}1'
a1a1a1a1a1a1a1a

但似乎gsub只在每个换行符后递增,所以我现在的解决方案是首先在每个“|”之后添加换行符,然后使用gsub并再次删除换行符:

> echo "a | a | a | a | a | a | a | a" | awk '{gsub(/\ \|\ /, " | \n")}1' | awk '{gsub(/\ \|\ /, ++i)}1' | tr -d '\n'
a1a2a3a4a5a6a7a

老实说,这只是恶心......

有更好的方法吗?

4 个答案:

答案 0 :(得分:7)

如果perl没问题:

$ echo 'a | a | a | a | a | a | a | a' | perl -pe 's/ *\| */$i++/ge'
a0a1a2a3a4a5a6a
  • *\| *匹配|被零个或多个空格包围
  • e修饰符允许在替换部分中使用Perl代码
  • $i++使用$i和增量值(默认值0

答案 1 :(得分:3)

您可以像这样使用awk

s="a | a | a | a | a | a | a | a"

awk -F ' *\\| *' -v OFS="" '{s=""; for(i=1; i<NF; i++) s = s $i i-1; print s $i}' <<< "$s"

a0a1a2a3a4a5a6a
  • -F ' *\\| *'会将可选空格包围的|设置为输入字段分隔符。
  • for循环遍历每个字段并在每个字段后附加字段递增位置。

答案 2 :(得分:0)

使用awk

的另一种解决方案
echo "a | a | a | a | a | a | a | a" | 
awk -v RS="[ ]+[|][ ]+" '{printf "%s%s",(f?NR-2:""),$0; f=1}'

你明白了,

a0a1a2a3a4a5a6a

答案 3 :(得分:0)

如果只使用sh是一个选项,那么可能会替换直到达到一个固定点:

s=$1  # first argument passed to script, "a | a | a |..."

n=0
while true
do
    prev=$s
    s=${s%" | a"}
    test "$s" = "$prev" && break
    result=$result${n}"a"
    n=$((n + 1))
done
echo $s$result

如果此程序存在于脚本文件digits.sh中,

$ sh digits.sh "a | a | a | a | a | a | a | a"
a0a1a2a3a4a5a6a
$