How to reform text string?

Greetings,

How can I turn this:

t70c7n133 16 t70c7n134 16 t70c7n135 16 t70c7n136 16 t70c7n137 16 t70c7n138 16 t70c7n140 16 t70c7n141 16

into this:

t70c7n133 slots=16
t70c7n134 slots=16
t70c7n135 slots=16
t70c7n136 slots=16
t70c7n137 slots=16
t70c7n138 slots=16
t70c7n140 slots=16
t70c7n141 slots=16

I've come up with a couple ways but they're ugly and I've gotten close with sed but I'm not that good with it. So I'm sure there are much cleaner ways than what I've cooked up.

Thanks in advance.

Show us what you've cooked up!

For the purpose of simplicity:

xargs -n2 < file|awk '{$2="slots="$2}1'

In pure awk (will fail if there are trailing spaces in the file though :():

awk 'BEGIN{RS=FS};ORS=(NR%2)?" slots=":"\n"{gsub(/\n *$/,"")}1'  file

Thank-you pilnet101 for freely chiming in. And yes RudiC I did put forth some effort before posting.

The following variable is inherited:

HOST_LIST='t70c7n133 16 t70c7n134 16 t70c7n135 16 t70c7n136 16 t70c7n137 16 t70c7n138 16 t70c7n140 16 t70c7n141 16'

and I did this:

echo $HOST_LIST | fold -w 13 | sed  's/16/slots=16/'

However I realized that if the 16 was actually a single digit then the fold command is no good. Of course pilnet101's solution works well:

echo $HOST_LIST | awk 'BEGIN{RS=FS};ORS=(NR%2)?" slots=":"\n"{gsub(/\n *$/,"")}1'

Any other suggestions?

With any shell that uses basic Bourne shell syntax:

#!/bin/ksh
HOST_LIST='t70c7n133 16 t70c7n134 16 t70c7n135 16 t70c7n136 16 t70c7n137 16 t70c7n138 16 t70c7n140 16 t70c7n141 16'
set -- $HOST_LIST
while [ $# -ge 2 ]
do	printf '%s slots=%s\n' "$1" "$2"
	shift 2
done

And with a recent bash , a 1993 or later version of ksh , or another shell that supports indexed arrays and arithmetic commands:

#!/bin/ksh
HOST_LIST='t70c7n133 16 t70c7n134 16 t70c7n135 16 t70c7n136 16 t70c7n137 16 t70c7n138 16 t70c7n140 16 t70c7n141 16'
array=( $HOST_LIST )
for ((i = 0; i < ${#array[@]}; i += 2))
do	printf '%s slots=%s\n' "${array}" "${array[i+1]}"
done

or with any POSIX-conforming shell that also supports indexed arrays as an extension to the standards:

#!/bin/ksh
HOST_LIST='t70c7n133 16 t70c7n134 16 t70c7n135 16 t70c7n136 16 t70c7n137 16 t70c7n138 16 t70c7n140 16 t70c7n141 16'
array=( $HOST_LIST )
i=0
while [ $i -lt ${#array[@]} ]
do	printf '%s slots=%s\n' "${array}" "${array[i+1]}"
	i=$((i + 2))
done

All of which produce the output:

t70c7n133 slots=16
t70c7n134 slots=16
t70c7n135 slots=16
t70c7n136 slots=16
t70c7n137 slots=16
t70c7n138 slots=16
t70c7n140 slots=16
t70c7n141 slots=16

As long as they are in pairs, you do not have to worry if the second member of the pair is a single digit or more or no digits at all.

echo $HOST_LIST | awk '{for(i=1;i<=NF;i+=2){printf "%s slots=%s\n", $i, $(i+1)}}'

Looking at coming up with another solution for this in pure shell, similar to Don's solutions - I have been trying to use parameter expansion/substitution. I can only envisage that this would be achievable by doing this only if back references are supported. Looking at several sources online - ksh93 supposedly supports them, can anyone confirm this?

Something along the lines of:

tmp=${HOST_LIST// / strings=}
echo ${tmp//strings=\([![:digit:]]\)/\1"\n"}

With the above code, bash version:

GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin14)

and ksh version:

Copyright (C) 2007 Free Software Foundation, Inc.
  version         sh (AT&T Research) 93u+ 2012-08-01

produce the output:

t70c7n133 strings=16 strings=t70c7n134 strings=16 strings=t70c7n135 strings=16 strings=t70c7n136 strings=16 strings=t70c7n137 strings=16 strings=t70c7n138 strings=16 strings=t70c7n140 strings=16 strings=t70c7n141 strings=16
1 Like

sed solution based on you own approach, leaving out fold :

echo $HOST_LIST | sed -r 's/ ([0-9]+)( |$)/ slots=\1\n/g;s/\n$//'
1 Like
$ printf "%s slots=%s\n" $HOST_LIST
t70c7n133 slots=16
t70c7n134 slots=16
t70c7n135 slots=16
t70c7n136 slots=16
t70c7n137 slots=16
t70c7n138 slots=16
t70c7n140 slots=16
t70c7n141 slots=16
5 Likes

Longhand using OSX 10.7.5, default terminal using sh...

#!/bin/sh
# reformat
HOST_LIST='t70c7n133 16 t70c7n134 16 t70c7n135 16 t70c7n136 16 t70c7n137 16 t70c7n138 16 t70c7n140 16 t70c7n141 16'
# Working section.
HOST_LIST=( $HOST_LIST )
for (( n=0; n < ${#HOST_LIST[@]}; n+=2 ))
do
	echo "${HOST_LIST[$n]} slots=${HOST_LIST[$((n+1))]}"
done > /tmp/text
# End of working section.
HOST_LIST=$( cat /tmp/text )
echo "$HOST_LIST"

Results:-

Last login: Sat Jun 27 08:18:39 on ttys000
AMIGA:barrywalker~> cd Desktop/Code/Shell
AMIGA:barrywalker~/Desktop/Code/Shell> ./reformat
t70c7n133 slots=16
t70c7n134 slots=16
t70c7n135 slots=16
t70c7n136 slots=16
t70c7n137 slots=16
t70c7n138 slots=16
t70c7n140 slots=16
t70c7n141 slots=16
AMIGA:barrywalker~/Desktop/Code/Shell> _

Thank-you all for the variety of solutions.