3

I have a script that concatenates output from two different variables. The issue is that the output of both variables contains multiple rows. So, the output isn't what I expect.

First variable and output:

snap_daily=`cat snaps.txt | grep test-for-dr | awk '{print $2}' | sed 's/[",]//g' | sed 's/test-for-dr-//g'`

2017-03-10-08-00
2017-03-10-11-00
2017-03-10-12-00
2017-03-10-14-00
2017-03-10-15-00

Second variable and output:

snap_prefix=`cat snaps.txt | grep test-for-dr | awk '{print $2}' | sed 's/[",]//g' | awk -F '2017' '{print $1}'

test-for-dr-
test-for-dr-
test-for-dr-
test-for-dr-
test-for-dr-

Code to concatenate and result:

 snap_name="$snap_prefix$snap_daily"

 test-for-dr-bdmprest- test-for-dr-bdmprest- test-for-dr-bdmprest- test-for-dr-bdmprest- test-for-dr-bdmprest-2017-03-10-08-00 2017-03-10-11-00 2017-03-10-12-00 2017-03-10-14-00 2017-03-10-15-00

Desired Result:

test-for-dr-2017-03-10-08-00
test-for-dr-2017-03-10-11-00
test-for-dr-2017-03-10-12-00
test-for-dr-2017-03-10-14-00
test-for-dr-2017-03-10-15-00

Essentially, I need each line to match from each respective line of output.

4 Answers 4

2

When you have 2 multi-line variables, there are a couple of ways to combine them:

  1. declare the vars for testing

    $ snap_prefix="test-for-dr-
    test-for-dr-
    test-for-dr-
    test-for-dr-
    test-for-dr-"
    $ snap_daily="2017-03-10-08-00
    2017-03-10-11-00
    2017-03-10-12-00
    2017-03-10-14-00
    2017-03-10-15-00"
    
  2. use a bash loop to read a line from each variable:

    while read -u3 prefix; read -u4 suffix; do 
        echo "$prefix$suffix"
    done 3<<<"$snap_prefix" 4<<<"$snap_daily"
    
  3. use pr to convert a single stream into 2 columns (and then tr to remove the tab character separating the columns)

    { echo "$snap_prefix"; echo "$snap_daily"; } | pr -2Ts | tr -d '\t'
    

2 and 3 both output:

test-for-dr-2017-03-10-08-00
test-for-dr-2017-03-10-11-00
test-for-dr-2017-03-10-12-00
test-for-dr-2017-03-10-14-00
test-for-dr-2017-03-10-15-00

BUT, I bet this would work with the input you haven't shown us:

grep -Eo 'test-for-dr-[[:digit:]-]+' snaps.txt
3
  • 1
    paste -d '\0' file1 file2 is the standard command to paste 2 files. So you could also do paste -d '\0' <(printf '%s\n' "$var1") <(printf '%s\n' "$var2") or simply paste -d '\0' <(<<<$var1) <(<<<$var2) in zsh Mar 14, 2017 at 15:10
  • The third solution worked great! Can't thank you enough.
    – AndG
    Mar 14, 2017 at 15:37
  • 2019, and this answer still useful to society! Mar 28, 2019 at 16:54
1

If the end goal is to rearrange and print field 2 from file snaps.txt, there is neither a need for intermediate variables nor a need for grep-sed-awk pipelines, a single awk invocation should be able to do the job

awk '$2 ~ /test-for-dr-/{
     gsub(/[",]/, "", $2)
     match($2, "test-for-dr-")
     printf "%s%s\n", substr($2, RSTART), substr($2, 1, RSTART-1)
     }' snaps.txt
1

Do as:

#!/bin/bash

cat snaps.txt | grep test-for-dr | awk '{print $2}' | sed 's/[",]//g' | sed 's/test-for-dr-//g' > snap_daily.txt
cat snaps.txt | grep test-for-dr | awk '{print $2}' | sed 's/[",]//g' | awk -F '2017' '{print $1}' > snap_prefix.txt

a=`cat snap_daily.txt | wc -l`
let x=1
for i in `cat snap_daily.txt`
do
snap_daily=`cat snap_daily.txt | sed -n "$x"p`
snap_prefix=`cat snap_prefix.txt | sed -n "$x"p`
if [[ $x -eq $a ]]
then exit 0
fi
echo $snap_daily$snap_prefix
let x++
done
0

One easy workaround is to use arrays since the results are returned with new lines:

$ IFS=$'\n' readarray -t a< <(echo $'2017-03-10-08-00\n2017-03-10-11-00\n2017-03-10-12-00\n2017-03-10-14-00\n2017-03-10-15-00\n')

$ IFS=$'\n' readarray -t b < <(echo $'test-for-dr-\ntest-for-dr-\ntest-for-dr-\ntest-for-dr-\ntest-for-dr-\n')

$ declare -p a b
declare -a a=([0]="2017-03-10-08-00" [1]="2017-03-10-11-00" [2]="2017-03-10-12-00" [3]="2017-03-10-14-00" [4]="2017-03-10-15-00" [5]="")
declare -a b=([0]="test-for-dr-" [1]="test-for-dr-" [2]="test-for-dr-" [3]="test-for-dr-" [4]="test-for-dr-" [5]="")

$ for ((i=0;i<"${#a[@]}";i++));do conc="${b[$i]}${a[$i]}";echo "$conc";done
test-for-dr-2017-03-10-08-00
test-for-dr-2017-03-10-11-00
test-for-dr-2017-03-10-12-00
test-for-dr-2017-03-10-14-00
test-for-dr-2017-03-10-15-00

Another solution would be use just an awk script to combine the results from all the files, but we need more details for that - maybe a new question.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .