?
Solved

unix, find and replace

Posted on 2014-08-07
8
Medium Priority
?
196 Views
Last Modified: 2014-10-20
I want to find and replace one string, finding is tricky for example if there are inputs values like below,
 boks_hjimn_cat, boks_hmm_dog, boks_go_rawst

I should replace boks_ begin values with addition value appended, but boks_ begin values and rawst end values should not be replaced. The output should be like this in the replaced file.
Db.boks_hjimn_cat,
Db.boks_hmm_dog,
boks_go_rawst.

I just gave example of 3 values but this file more than 200 pattern of this type.
Please let me know if there is a combination of find, awk or sed commands.
0
Comment
Question by:welcome 123
  • 5
  • 2
8 Comments
 
LVL 48

Expert Comment

by:Tintin
ID: 40247815
Your description is unclear.

Are you saying any string that starts with boks_ and ends with rawst should NOT be replaced and all other variations should?
0
 
LVL 23

Accepted Solution

by:
savone earned 2000 total points
ID: 40247913
This would probably work, although you might end up with a comma at then end of the last line.  Not sure if that is a deal breaker or not. It would also be a lot simpler if you knew how many value there were in the CSV file.  This code is assuming you are using a file named pat.csv (which I tested on), please change that to match your needs.

#!/bin/bash
FIELD=1
COUNT=`sed 's/[^,]//g' pat.csv | wc -c`; let "COUNT+=1"

while [ "$FIELD" -lt "$COUNT" ]; do 
	CONTENT=`cat pat.csv | cut -d, -f$FIELD`
	if [[ "$CONTENT" == *rawst* ]]; then
		echo "$CONTENT,"
		let "FIELD+=1"
		continue
	else
		echo "Db.$CONTENT,"
		let "FIELD+=1"
	fi
done

Open in new window

0
 

Author Comment

by:welcome 123
ID: 40247958
Actually my input file is a txt file with multiple sql queries. This file has words like boks_hjimn_cat, boks_hmm_dog, boks_go_rawst etc in random postions. I need to find the words beginning with boks_ but the word should not end with _rawst and append Db. in the beginning to those words.

so, boks_hjimn_cat should be replaced as Db.boks_hjimn_cat,  
boks_hmm_dog should be replaced as Db.boks_hmm_dog
but the word boks_go_rawst should remain same boks_go_rawst .

If I use sed\"boks_"\"Db.boks_"\ then all the words are replaced, even the one ending with rawst,
so can you suggest how to do that?
This can be either perl script or unix script or sed or awk command, find, replace  etc.
0
Granular recovery for Microsoft Exchange

With Veeam Explorer for Microsoft Exchange you can choose the Exchange Servers and restore points you’re interested in, and Veeam Explorer will present the contents of those mailbox stores for browsing, searching and exporting.

 
LVL 23

Expert Comment

by:savone
ID: 40247960
Can you give us an example of the file? It's hard to visualize what your saying.  Are they all on one line?  Each on their own line? etc...
0
 

Author Comment

by:welcome 123
ID: 40247968
Even using find and replace with vi editor is also fine with you suggest me the correct expression.
0
 

Author Comment

by:welcome 123
ID: 40247977
The file is  a  perl module having several functions. In some of the functions the script is using select * from boks_go_rawst  or set .boks_hjimn_cat = 1; or update boks_hmm_dog etc.
0
 

Author Comment

by:welcome 123
ID: 40248016
OK, wrote this script and it should probably work but this one is replacing all tabs and extra spaces in my original file to single space.

#!/usr/bin/perl -w

use strict;
use IO::File; #for filehandle
use File::Basename;
use File::Copy;
use Data::Dumper;

my $File = "C:\\scripts\\input.pm";
my $WriteFile = "C:\\scripts\\input1.pm";
my @newfile;

      if (open (FILE, "< $File" )) {
            my @secdata = <FILE>;
            close FILE;
            foreach my $secline (@secdata) {
                  chomp $secline;
                  my @line = split (/\s/, $secline);
                  my @newline;
                  foreach my $word (@line) {
                        chomp $word;
                        if(($word =~ /boks_/) && ($word !~ /rawst/)) {
                              $word = "Dat." . $word;
                        }
                        push (@newline, $word);
                  }
                  push (@newline, "\n");
                  push (@newfile, join(' ', @newline));
                      
            }
            
      }
      else {
            print "Cannot open the File $File for reading $!\n"
      }
      
      print Data::Dumper->Dump([\@newfile], [qw(*newfile)]);
       if ( open(LOG, ">$WriteFile"))   {
          print LOG @newfile;
        close LOG;
      }
      else {
            print "Cannot open the File $WriteFile for writing$!\n"
      }
0
 

Author Comment

by:welcome 123
ID: 40248044
Finally the below solution seems to be working.

#!/usr/bin/perl -w

use strict;
use IO::File; #for filehandle
use File::Basename;
use File::Copy;
use Data::Dumper;

my $File = "C:\\scripts\\input.pm";
my $WriteFile = "C:\\scripts\\input1.pm";
my @newfile;
if (open (FILE, "< $File" )) {
      my @secdata = <FILE>;
      close FILE;
      foreach my $secline (@secdata) {
            chomp $secline;
            my @line = split (/ /, $secline);
            my @newline;
            foreach my $word (@line) {
                  chomp $word;
                  if(($word =~ /boks_/) && ($word !~ /rawst/)) {
                        $word = "Dat." . $word;
                  }
                  push (@newline, $word);
            }
            my $newlinestr = join(' ', @newline);
            $newlinestr=~s/\s+$//g;
            $newlinestr .= "\n";
            push (@newfile, $newlinestr);
                  
      }
            
}
else {
      print "Cannot open the File $File for reading $!\n"
}
      
#print Data::Dumper->Dump([\@newfile], [qw(*newfile)]);
if ( open(LOG, ">$WriteFile"))   {
      print LOG @newfile;
      close LOG;
}
else {
      print "Cannot open the File $WriteFile for writing$!\n"
}
0

Featured Post

Fill in the form and get your FREE NFR key NOW!

Veeam is happy to provide a FREE NFR server license to certified engineers, trainers, and bloggers.  It allows for the non‑production use of Veeam Agent for Microsoft Windows. This license is valid for five workstations and two servers.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Using 'screen' for session sharing, The Simple Edition Step 1: user starts session with command: screen Step 2: other user (logged in with same user account) connects with command: screen -x Done. Both users are connected to the same CLI sessio…
It’s 2016. Password authentication should be dead — or at least close to dying. But, unfortunately, it has not traversed Quagga stage yet. Using password authentication is like laundering hotel guest linens with a washboard — it’s Passé.
Learn how to get help with Linux/Unix bash shell commands. Use help to read help documents for built in bash shell commands.: Use man to interface with the online reference manuals for shell commands.: Use man to search man pages for unknown command…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
Suggested Courses
Course of the Month16 days, 14 hours left to enroll

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question