Find the answer to your Linux question:
Results 1 to 6 of 6
Like Tree3Likes
  • 1 Post By atreyu
  • 1 Post By drl
  • 1 Post By atreyu
Hi I would like to search in replace expressions in a text file (target file), using expressions from another text file (expressions file) that looks like this: stringtosearch1 [tab] replacementstring1 ...
  1. #1
    Just Joined!
    Join Date
    Nov 2010
    Posts
    15

    Search and replace in a file using expressions from another file

    Hi

    I would like to search in replace expressions in a text file (target file), using expressions from another text file (expressions file) that looks like this:
    stringtosearch1 [tab] replacementstring1
    stringtosearch2 [tab] replacementstring2
    stringtosearch3 [tab] replacementstring3
    ...

    Can somebody help me on this?
    Thanks.

  2. #2
    Linux Guru
    Join Date
    May 2011
    Posts
    1,843
    If your "expressions-file.txt" file looks like this:
    Code:
    stringy1        shiny1
    stringy2        shiny2
    stringy3        shiny3
    and your "target-file.txt" file looks something like this:
    Code:
    stringy0
    stringy1
    foo 
    stringy2
    bar 
    stringy3
    blah
    You could try this:
    Code:
    #!/bin/bash
    
    # define location of the two required files
    exprFile=./expressions-file.txt
    targFile=./target-file.txt
    for file in $expressionsFile $targetFile; do
      ! [ -f $file ] && echo $file: No such file && exit 1
    done
    
    # iterate over the expressions file, line by line
    cat $exprFile|while read line; do
    
      # store columnar date in an array
      declare -a array
      array=($echo $line)
    
      # make sure exactly two columns of data are provided on each line
      if [ ${#array[*]} -ne 2 ]; then
        echo "Need exactly two columns - skipping line"
        continue
      fi
    
      search=${array[0]}
      replace=${array[1]}
    
      # do the inline replacement with sed, saving to a backup file
    #  echo replacing $search with $replace in $targFile..
      sed -i.bak s/$search/$replace/g $targFile
    
    done
    It should output this:
    Code:
    stringy0
    shiny1
    foo
    shiny2
    bar
    shiny3
    blah
    Irithori likes this.

  3. #3
    Just Joined!
    Join Date
    Nov 2010
    Posts
    15
    Thanks a lot!

    Will it work with a file with various format of text and sentences like this:

    Code:
    Stringy0, blabla stringy1. Bfoo stringy2 ar   stringy3 blah; blablablabla.
    Can I make it case sensitive?

    Thank you.

  4. #4
    drl
    drl is offline
    Linux Engineer drl's Avatar
    Join Date
    Apr 2006
    Location
    Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
    Posts
    1,117
    Hi.

    An alternative is to transform the pattern file into sed substitution expressions and use sed to read the resulting pattern file, applying the changes to a main data file. Here is a sample script that displays the context, the strings file, the resulting patterns file, the main data file and the final file with old strings replaced by new strings:
    Code:
    #!/usr/bin/env bash
    
    # @(#) s1	Demonstrate creation and execution of sed script.
    
    # Utility functions: print-as-echo, print-line-with-visual-space, debug.
    # export PATH="/usr/local/bin:/usr/bin:/bin"
    pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
    pl() { pe;pe "-----" ;pe "$*"; }
    db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
    db() { : ; }
    C=$HOME/bin/context && [ -f $C ] && . $C sed
    
    r=data2
    m=data1
    
    pl " Input data file, replacements, $r:"
    cat $r
    
    pl " Results of creating pattern file:"
    rm -f patterns
    sed 's|\(.*\)\t\(.*\)|s/\1/\2/g|' $r |
    tee patterns
    
    pl " Main data file $m:"
    cat $m
    
    pl " Results of applying pattern file with sed to main data file:"
    sed -f patterns $m
    
    exit 0
    producing:
    Code:
    % ./s1
    
    Environment: LC_ALL = C, LANG = C
    (Versions displayed with local utility "version")
    OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
    Distribution        : Debian GNU/Linux 5.0.8 (lenny) 
    GNU bash 3.2.39
    GNU sed version 4.1.5
    
    -----
     Input data file, replacements, data2:
    stringy1	shiny1
    stringy2	shiny2
    stringy3	shiny3
    
    -----
     Results of creating pattern file:
    s/stringy1/shiny1/g
    s/stringy2/shiny2/g
    s/stringy3/shiny3/g
    
    -----
     Main data file data1:
    stringy0
    stringy1
    foo 
    stringy2
    bar 
    stringy3
    blah
    Stringy0, blabla stringy1. Bfoo stringy2 ar   stringy3 blah; blablablabla.
    
    -----
     Results of applying pattern file with sed to main data file:
    stringy0
    shiny1
    foo 
    shiny2
    bar 
    shiny3
    blah
    Stringy0, blabla shiny1. Bfoo shiny2 ar   shiny3 blah; blablablabla.
    The advantage to this extra work is that there needs to be only a single pass over the main data file. For small data files and a small number of replacements there probably is not much of a gain.

    Best wishes ... cheers, drl
    louisJ likes this.
    Welcome - get the most out of the forum by reading forum basics and guidelines: click here.
    90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
    We look forward to helping you with the challenge of the other 10%.
    ( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )

  5. #5
    Linux Guru
    Join Date
    May 2011
    Posts
    1,843
    Quote Originally Posted by louisJ View Post
    Will it work with a file with various format of text and sentences like this:

    Code:
    Stringy0, blabla stringy1. Bfoo stringy2 ar   stringy3 blah; blablablabla.
    Well, the short answer is yes, you can do pretty much whatever text mangling you can imagine with awk/sed/grep (or perl!). But I don't understand what you want, based upon the example file you gave. Is it an example of the expressions file or the target file?

    Can I make it case sensitive?
    It already is! By default, "Linux is case-sensitive". You'd make this script case-insensitive by tacking on the i switch to the sed command (after the /g).
    louisJ likes this.

  6. #6
    Just Joined!
    Join Date
    Nov 2010
    Posts
    15
    Atreyu it was the target file.
    But you pretty much answerd the question.

    Thanks to both of you Drl and Atreyu for helping.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...