Anything better than what I wrote in here

/Users/ManoharMangala/rsync/$ cat mytestfile | head -15

sint2570.pers.ops.ctec.mdw.com

/opt/rsync

sint1120.pers.ops.ctec.mdw.com

sar actions

rum mill ops

backup

restart

sycn

sint2550.pers.div.ops.ctec.mdw.com

/opt/rsync

/opt/wick_rsync

/Users/ManoharMangala/rsync/$

Expected Output.


sint2570.pers.ops.ctec.mdw.com : /opt/rsync
sint1120.pers.ops.ctec.mdw.com : sar actions|| rum mill ops|| backup ||  restart || sycn
sint2550.pers.div.ops.ctec.mdw.com: /opt/rsync || /opt/wick_rsync

What I wrote -

/Users/ManoharMangala/rsync/$cat myscript.sh

#!/bin/bash

input="mytestfile"

arr=()

while IFS= read -r line

do

echo "$line" | grep -qi "com"

arr+=("$line ||")

done < "$input"

echo "${arr[@]}"

/Users/ManoharMangala/rsync/$./myscript.sh | sed 's/sint/\
sint/g'
sint02.pers.ops.ctec.mdw.com || /opt/rsync ||
sint01.pers.ops.ctec.mdw.com || sar actions || rum mill ops || backup || restart || sycn ||
sint25.pers.div.ops.ctec.mdw.com || /opt/rsync || /opt/wick_rsync ||

Not really conversant with this sort of thing but I came up with the above. The myscript.sh works great to the extent that it certainly builds this huge array.
The issue/challenge here is there are 500 such nodes and they begin with trin[00-99],oper[00-99],opss[00-99],eng[00-99],sint[00-99] and I am not comfortable with the sed that I wrote in here.
Any ideas as to how to go about this would be of great help.

how about this - a bit verbose....

awk -f  mano.awk mytestfile

where mano.awk is:

BEGIN {
  OFS=" : "
}
!NF{next}
/[.]/ { sint=$1; next}
{a[sint]=(sint in a)?a[sint] " || " $0: $0}
END {
  for (i in a)
      print i, a[i]
}

results in:

sint1120.pers.ops.ctec.mdw.com : sar actions || rum mill ops || backup || restart || sycn
sint2570.pers.ops.ctec.mdw.com : /opt/rsync
sint2550.pers.div.ops.ctec.mdw.com : /opt/rsync || /opt/wick_rsync
2 Likes

@vgersh99 .,

Just to give you some context, we are porting scripts from one set of hosts to another set of hosts.

Cant thank you enough for your awk scrip. If you can explain the program that you wrote in here, it would be ideal.

Also, there is this next part of the task as well. So, I have this file below.

sint1120.pers.ops.ctec.mdw.com : sar actions || rum mill ops || backup || restart || sync
sint2570.pers.ops.ctec.mdw.com : /opt/rsync
eng1330.pers.div.ops.ctec.mdw.com : wick_rsync
eng1223.pers.div.ops.ctec.mdw.com : wick_rsync
trin0023.pers.div.ops.ctec.mdw.com :  wick_rsync || restart || backup | sync
trin0190.pers.div.ops.ctec.mdw.com :  wick_rsync || restart
trin0221.pers.div.ops.ctec.mdw.com :  wick_rsync

Now, from the above file, I need to ssh to everyone of the hosts that is in the first column and echo out the text that is between the delimiters, which are "||" in the folder /opt/. The tougher part here is, there is not just one or two such columns and the lines can be many.
So, how do I do the following for each line

  1. ssh to that host (which is the first column) .. this is bit easy as I can use read line
  2. echo out the next set of text that is between each "||" as a new line ?
  3. Here is the expected output for lets say on the host, -trin0023.pers.div.ops.ctec.mdw.com
     trin0023.pers.div.ops.ctec.mdw.com : rsync$ hostname; date; pwd; ls -altr
    trin0023.pers.div.ops.ctec.mdw.com
    Sat Jun 20 23:25:43 PDT 2020
     /opt/rsync
     -rwxr-xr-x   1 User  staff   245 Jun 20 03:19 wick_rsync
     -rwxr-xr-x   1 User  staff   146 Jun 20 03:42 restart
     -rwxr-xr-x   1 User  staff   337 Jun 20 04:13 backup
     -rwxr-xr-x   1 User  staff   337 Jun 20 04:13 sync
     drwxr-xr-x+ 86 User  staff  2924 Jun 20 04:13 ..
     drwxr-xr-x   5 User  staff   170 Jun 20 04:13 .

Now, if you think that any of the above steps I took to arrive at the end result do not make sense and this task can be easily done in any other way, please educate me and I shall follow your word.

best,
ManoharMa.

@vgersh99.,
Thank you so very much btw.

best,
ManoharMa

I would use the original file and your initial attempt with bash.

#!/bin/bash
input="mytestfile"

do_ssh(){
  [[ -n $host ]] &&
  ssh -nx "$host" "
    echo 'running on $host'
    printf '%s\n' '${arr[@]}'
"
}

host=
while IFS= read line <&3
do
  if [[ $line == *. * ]]
  then
    do_ssh
    host=$line
    arr=()
  else
    arr+=("$line")
  fi
done 3< "$input"
do_ssh

For extra safety I used descriptor 3 rather than the default (that is 0).
Because in the input there is no "end of actions" indicator the ssh action must occur again at the end - reason enough for a function.

1 Like

@MadeInGermany thank you !

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.