0

I have a file with Server and Domain names in it as below.

Names.txt :

ABCDomain ContractABCServer_1
ABCDomain ABC_server1
LinkDomain CoreLinkServer_1
TADDomain TADServer_1

(I'm getting above file after performing sort and unique operations to some other file.)---just additional info

I need to extract values from above file and pass it to a xyz command (the command is used to restart servers) as a parameter in below format.

O/P:

"ABCDomain(server:ContractABCServer_1,server:ABC_server1)","LinkDomain(server:CoreLinkServer_1)","TADDomain(TADServer_1)"

I m using below stated logic, but it doesn't give me the desired output as the DomainName has to come just once for each set. Also I m having trouble in keeping the same line.

-----------START------

    DOMAIN=''

IFS=' '
while read line
do
        DOMAIN=$(echo "$line" | awk -F " " '{print $1}')

        for word in $line
        do
                if [[ "$word" == "$DOMAIN" ]]; then
                        Server=$(echo "$line" | awk -F " " '{print $2}' )
                        echo -n "(server:$ServerName"
                fi

        done

done < Names.txt
Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232

4 Answers4

0

You can use this code, please read the code before executing it as it is creating a directory in /tmp folder named domains and then removing it the end

 DOMAIN=''

    IFS=' '
    declare -A domain
    mkdir /tmp/domains
    while read line
    do
            DOMAIN=$(echo $line | awk  '{print $1}')
            SERVER=$(echo $line | awk '{print $2}' )
            echo "$SERVER," >> /tmp/domains/$DOMAIN
            domain[$DOMAIN]=1
    done < Names.txt

    sed -ir "$ s/.,$//" /tmp/domains/*

    for i in "${!domain[@]}"; do
             echo -n "$i(server:";
             while read line ; do
                 echo -n "$line" ;
             done < /tmp/domains/$i
             echo ")"
    done
    rm -rf /tmp/domains

This is creating a folder in /tmp folder with the following data, such that each Domain file name has a list of Servers contained in them

$ ls -lhtr /tmp/domains/
total 12K
-rw-rw-r-- 1 arushirai arushirai 11 Jun 19 17:54 TADDomain
-rw-rw-r-- 1 arushirai arushirai 16 Jun 19 17:54 LinkDomain
-rw-rw-r-- 1 arushirai arushirai 32 Jun 19 17:54 ABCDomain

$ cat /tmp/domains/ABCDomain 
ContractABCServer_1,
ABC_server
$ cat /tmp/domains/LinkDomain 
CoreLinkServer_
$ cat /tmp/domains/TADDomain 
TADServer_
Arushix
  • 1,290
0

You can assemble the comma-separated strings directly in awk and print the composite at the end:

  $1 == "ABCDomain"  {d = (d == "") ? $2 : d "," $2; next} 
  $1 == "LinkDomain" {l = (l == "") ? $2 : l "," $2; next} 
  $1 == "TADDomain"  {t = (t == "") ? $2 : t "," $2; next} 

  END {
    printf("\"ABCDomain(server:%s)\",\"LinkDomain(server:%s)\",\"TADDomain(%s)\"\n", d, l, t)
  }

Ex.

$ awk '
  $1 == "ABCDomain"  {d = (d == "") ? $2 : d "," $2; next} 
  $1 == "LinkDomain" {l = (l == "") ? $2 : l "," $2; next} 
  $1 == "TADDomain"  {t = (t == "") ? $2 : t "," $2; next} 

  END {
    printf("\"ABCDomain(server:%s)\",\"LinkDomain(server:%s)\",\"TADDomain(%s)\"\n", d, l, t)
  }' Names.txt
"ABCDomain(server:ContractABCServer_1,ABC_server1)","LinkDomain(server:CoreLinkServer_1)","TADDomain(TADServer_1)"
steeldriver
  • 81,074
0
{
    if (dom[$1]) 
        dom[$1]=dom[$1]","$2
    else 
        dom[$1]=$2
} 

END {
    ORS=",";
    for (d in dom)
        if (d)
            print ("\""d"(server:"dom[d]")""\"")
}

This is quick and dirty awk solution. Save it like something.awk, then run:

awk -f something.awk Names.txt 

A quick fix in reply to your comment:

{ dom[$1]=dom[$1] ? dom[$1]",server:"$2 : "server:"$2 }

END {
    for (d in dom)
        if (d) {
            out && out = out","
            out = out"\""d"("dom[d]")""\""
        }
        print out
}
  • I used it and it has worked perfectly well. But there is a little change in the required o/p as below.

    "ABCDomain(server:ContractABCServer_1,server:ABC_server1)"

    I need "server" string before every server, not just at the beginning. Sorry for the previous typo.

    Hope it's possible

    – Aditya Telang Jun 21 '18 at 10:03
  • Can it be done. – Aditya Telang Jun 26 '18 at 12:13
0

(Updated to correct the output format)

Using awk:

BEGIN { OFS = "," }

{ servers[$1] = (servers[$1] == "" ? "server:" $2 : servers[$1] "," "server:" $2 ) }

END {
    $0 = ""
    for (domain in servers)
        $(++n) = sprintf("\"%s(%s)\"", domain, servers[domain])

    print
}

This would add the servers as a comma-delimited string to the specific domain in the main block while parsing the input file. This is done by modifying the servers array which holds the servers for a particular domain (the domain is the key in the array).

In the END block, we loop over all keys/domains in the servers array and create an output record in the specified format.

Running this on the supplied data:

$ awk -f script.awk names.txt
"TADDomain(server:TADServer_1)","ABCDomain(server:ContractABCServer_1,server:ABC_server1)","LinkDomain(server:CoreLinkServer_1)"

A mostly equivalent bash script (requires bash 4.3+ for the associative array):

declare -A servers

while read domain server; do
    servers[$domain]+="${servers[$domain]:+,}server:$server"
done <names.txt

for domain in "${!servers[@]}"; do
    out+="${out:+,}\"$domain(${servers[$domain]})\""
done

printf '%s\n' "$out"

... but see "Why is using a shell loop to process text considered bad practice?".

Kusalananda
  • 333,661
  • Thanks. About the artice "Why is using a shell loop....." I read it, but I m still learning to use text processing basics. – Aditya Telang Jun 27 '18 at 09:03
  • How can we neglect the single quotes that appear while accessing a variable using "$". Is there any other way of calling a variable that doesn't give single quotes. – Aditya Telang Jun 27 '18 at 12:20
  • @AdityaTelang I'm not quite of which single quotes you refer to. – Kusalananda Jun 27 '18 at 12:28
  • Let's say I have a command xyz.sh and I have stored the value of awk -f script.awk names.txt in a variable called PARAM. Now I run the command in script like below:-

    xyz.sh -domains $PARAM

    Here the $PARAM is resolving into --> '"TADDomain(server:TADServer_1)"' instead of "TADDomain(server:TADServer_1)" Extra quotes are comming at end and begginning which is corrupting the command.

    – Aditya Telang Jun 27 '18 at 12:41