I have a file having the below values:

cat data.txt

server1: 'calv'
server2: 'anot'
log: '/u/log/1'
server3: 'calv'
server4: 'anot'
server5: 'secd'
server6: 'calv'
LIB_TRGT_calv,anot: '/tmp/hello.txt'
LIB_TRGT_secd: '/var/del.tmp'

I get the variables containing _TRGT_ i.e LIB_TRGT_calv,anot & LIB_TRGT_secd

Note: the names of the variable could be different like DB_TRGT_<whatever>

I need to get the names after _TRGT_ from the variable above i.e calv,anot and secd.

considering we got calv & anot & secd; I now need to get all the entries having calv & anot & secd and add those found entries in the data.txt as below:

Desired Output:

server1: 'calv'
server2: 'anot'
log: '/u/log/1'
server3: 'calv'
server4: 'anot'
server5: 'secd'
server6: 'calv'
LIB_TRGT_calv,anot: '/tmp/hello.txt'
LIB_TRGT_secd: '/var/del.tmp'
LIB_server1:  '/tmp/hello.txt'
LIB_server2:  '/tmp/hello.txt'
LIB_server3:  '/tmp/hello.txt'
LIB_server4:  '/tmp/hello.txt'
LIB_server6:  '/tmp/hello.txt'
LIB_server5: '/var/del.tmp'

Below is what I did so far:

grep TRGT* data.txt | cut -d: -f1 |cut -d_ -f3


grep TRGT* test.txt | cut -d: -f1 |cut -d_ -f3 | sed -n 1'p' | tr ',' '\n'

I m not sure how to use xargs and further go about it.

  • I see you have now added quotes to your values. Is the file in fact a YAML file?
    – Kusalananda
    Apr 24 at 22:00
  • Yes, It dumps a YAML
    – Ashar
    Apr 24 at 22:03
  • 1
    How is this different from your previous question and why isn't your starting point the code from the previous answer you got?
    – Ed Morton
    Apr 24 at 22:08
  • This is different as the Solution provided in the previous works strictly for keys starting with LIB_TRGT_ while here the requirement is <anything>_TRGT_. Also, the value here is enclosed in singlequotes '. Thus the solution there does not work here @Ed Morton
    – Ashar
    Apr 24 at 22:15
  • 2
    Then state THAT in your problem and provide THAT script as the starting point and reference your previous question for context, don't have us start all over again with a pile of greps, cuts, seds, etc. in a pipeline as if you hadn't already got most of the solution you need.
    – Ed Morton
    Apr 24 at 22:21

1 Answer 1


Since this is YAML, I'd use a YAML parser, such as yq from https://kislyuk.github.io/yq/

Given the input data in file and a short script in script:

$ yq -y -f script file
server1: calv
server2: anot
log: /u/log/1
server3: calv
server4: anot
server5: secd
server6: calv
LIB_TRGT_calv,anot: /tmp/hello.txt
LIB_TRGT_secd: /var/del.tmp
LIB_server1: /tmp/hello.txt
LIB_server2: /tmp/hello.txt
LIB_server3: /tmp/hello.txt
LIB_server4: /tmp/hello.txt
LIB_server5: /var/del.tmp
LIB_server6: /tmp/hello.txt

This was done using the following jq script (yq is a YAML wrapper around the jq JSON parser):

        select(.key | test("_TRGT_")) |
        .value as $v |
        .key | sub(".*_TRGT_"; "") | split(",")[] |
        { key: ., value: $v }
) as $map |
. += with_entries(
        select(.value | in($map)) |
        { key: ("LIB_" + .key), value: $map[.value] }

This first computes the JSON object $map, which, given the data in the question, will be a simple map between the special key values, parsed out from the _TRGT_ keys in the original data, and the pathnames:

  "calv": "/tmp/hello.txt",
  "anot": "/tmp/hello.txt",
  "secd": "/var/del.tmp"

For each value in the original data that corresponds to a key in this $map object, a new entry is created with the key computed from value's key and the value taken from the corresponding entry in $map.

Not the answer you're looking for? Browse other questions tagged or ask your own question.