How to replace placeholder strings in document with contents from a file

6,106

Solution 1

You may transform the mappings into a sed editing script like this:

$ sed -r 's#^([^[:blank:]]*)[[:blank:]]+(.*)#s/<@\1>/\2/g#' user_map.txt >script.sed

Given the example, this will produce script.sed with the contents

s/<@U39RFF91U>/Person1/g
s/<@U2UNRTLBV>/Person2/g

You may then apply this editing script to the text file:

$ sed -f script.sed letter.txt >completed_letter.txt

Solution 2

Can be done either with sed or even using just bash tools .

Classic bash solution:

var="$(cat file.txt)";while read -r id name;do var="${var//@$id/$name}";done<mapfile.txt;echo "$var"

You can append >newfile.txt to the last command to send the final text in a newfile.

Sed solution with writting changes to the same file:

while read -r id name;do sed -i "s/\@$id/$name/g" textfile.txt;done<mapfile.txt

This solution may perform slower if mapfile / text file are quite large, since external app sed is called for every entry found stored in map file.

Both solutions work ok with your sample.

$ cat b.txt
<@U39RFF91U> for all the help in this project!
Thanks for your help to enhance the data quality <@U2UNRTLBV> <@U39RFF91U> <@U2UQCN023>!

$ cat c.txt
U39RFF91U  Person1
U2UNRTLBV  Person2

$ var="$(cat b.txt)";while read -r id name;do var="${var//@$id/$name}";done<c.txt #Batch Solution
$ echo "$var" 
<Person1> for all the help in this project!
Thanks for your help to enhance the data quality <Person2> <Person1> <@U2UQCN023>!

$ while read -r id name;do sed -i "s/\@$id/$name/g" b.txt;done<c.txt #SED solution
$ cat b.txt
<Person1> for all the help in this project!
Thanks for your help to enhance the data quality <Person2> <Person1> <@U2UQCN023>!
Share:
6,106

Related videos on Youtube

Glen31
Author by

Glen31

Updated on September 18, 2022

Comments

  • Glen31
    Glen31 over 1 year

    I have two files, A and B.

    File A is a letter, as below, which contains several placeholder strings on each line, like <@userid>.

    <@U39RFF91U> for all the help in this project!
    
    Thanks for your help to enhance the data quality <@U2UNRTLBV> <@U39RFF91U> <@U2UQCN023>!
    Thanks for <@U38F4TBQ9> <@U38F5PQ73> <@U38F747CZ> <@U39RT0G07> and <@U2UQ17U20> ’s great work at the New Product!
    
    
    Successful release! <@U2WHAAU9H> <@U2ML3C551> <@U38F4TBQ9> <@U38F747CZ> <@U39RT0G07> <@U2UQ17U20> <@U38F5PQ73> <@U2N64H7C6>!
    
    Praise <@U2X0APW3Y> for going above and beyond to help with the retail campaign!
    

    File B is a mapping table, mapping all user IDs to each user's name:

    U39RFF91U  Person1
    U2UNRTLBV  Person2
    

    I'd like to work out a final file, C, with the content from the letter in A, but with all placeholders replaced by the corresponding content from the mapping table in file B.

    Any idea how to do it via shell script on Linux?

    • upkar
      upkar over 7 years
      Can you paste a sample output, how it is required
    • upkar
      upkar over 7 years
      Is the required output. for checking defind person 1 as upkar. Also user name is not hardcoded it will refer from file B only Upkar. for all the help in this project! Thanks for your help to enhance the data quality Karup Upkar <@U2UQCN023>! Thanks for <@U38F4TBQ9> <@U38F5PQ73> <@U38F747CZ> <@U39RT0G07> and <@U2UQ17U20> .s great work at the New Product! Successful release! <@U2WHAAU9H> <@U2ML3C551> <@U38F4TBQ9> <@U38F747CZ> <@U39RT0G07> <@U2UQ17U20> <@U38F5PQ73> <@U2N64H7C6>! Praise <@U2X0APW3Y> for going above and beyond to help with the retail campaign!
    • George Vasiliou
      George Vasiliou over 7 years
      Is it possible names map table to have spaces in user name and/or user id?
  • Wildcard
    Wildcard over 7 years
    This is a case where awk is more trouble than it's worth. Just handle the first space delimiter explicitly, using sed, and you don't have to worry about spaces in the person names.
  • Kusalananda
    Kusalananda over 7 years
    @Wildcard I was lazy and added support for multi-word names as an afterthought. Fixed it now. Thanks for the poke.
  • mug896
    mug896 over 7 years
    I have updated my answer.