LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-02-2013, 04:07 AM   #1
Jalcock501
LQ Newbie
 
Registered: Aug 2013
Posts: 8

Rep: Reputation: Disabled
Searching/replacing string for string


Hi Guys

I'm trying to write a script that searches on a string in a single file, the file will never change neither will its format. I need to be able to search a string say "ABC10" and replace a byte on the same line as that string unfortunately shell scripting is not my strong suit so I was hoping someone would be able to give me a hand, or at least point me in the right direction as I've been searching for ages and the only string searches I can find is for multiple files, I only need to edit the one.

Thanks Guys
Jim
 
Old 08-02-2013, 04:22 AM   #2
kooru
Senior Member
 
Registered: Sep 2012
Posts: 1,385

Rep: Reputation: 275Reputation: 275Reputation: 275
I don't know if i undesrtand what you want.
But if you want to search a string into a file a change it, try this:

Code:
sed -i 's/ABC10/new_string_what_you_want/g' your_file
 
Old 08-02-2013, 04:22 AM   #3
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Without details on what you want/need (examples infile and wanted output) it is hard to help you.

One thing that comes to mind: Are we talking about a text file or a binary file.

Text files can be easily manipulated using, for example: sed, awk, perl and bash. Which is best and how to use them depends on what you want/need.
 
Old 08-02-2013, 04:31 AM   #4
Jalcock501
LQ Newbie
 
Registered: Aug 2013
Posts: 8

Original Poster
Rep: Reputation: Disabled
Hi Guys

Sorry about the ambiguity I'll try and explain a bit better. So I have a massive text file which holds information on certain users, this is an example users information;

001BOB DYLAN 14000100100100100000100101072000KFI0000007000100010N0
0

I need to search for the unique identifier i.e KFI and amend the permissions for the user (the unlined digit) but I want to be able to create a robust script so that other users can amend this. However I have no perl or bash knowledge

I have so code that I have attempted in perl however its mostly sudo

#!/usr/bin/perl -w

use strict;

print "Enter mnemonic";
$mnemonic=<>;

open FILE, "USERINFO.HEX" || die "error opening USERINFO.HEX";
while ($line=<FILE>)
{
if($line=/$mnemonic/)
{
change permissions
}

Last edited by Jalcock501; 08-02-2013 at 04:31 AM. Reason: spelling mistake
 
Old 08-02-2013, 04:41 AM   #5
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192
Firstly, please us [code][/code] tags to make your code legible.

As for a solution, it will depend ... in your example you say 'KFI' is the identifier, can we then assume that those letters will not appear anywhere else in the file in that exact order?
As for the replacement, how are we to know which of the large amount of zeroes is to be replaced? Is it always the third from the end?

As you can see, you need to be a lot clearer if we are to assist.
 
Old 08-02-2013, 04:47 AM   #6
Jalcock501
LQ Newbie
 
Registered: Aug 2013
Posts: 8

Original Poster
Rep: Reputation: Disabled
Sorry again I am new to this forum. KFI is a unique identifier so it can't appear anywhere else in the file, and yes the 0 that needs amending is always going to be 74 bytes into the text file.

Last edited by Jalcock501; 08-02-2013 at 07:37 AM.
 
Old 08-02-2013, 08:14 AM   #7
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
If you wonder why no-one has posted a follow-up message: Its still not clear what you want/need.....

Code:
001BOB DYLAN 14000100100100100000100101072000KFI0000007000100010N0
0
- Do all the entries contain 2 lines?
- If the token (KFI in this case) is found, does the 0 (third from last char) need to be replaced by the entry on the second line?
- If not, where does the input come from (I.e.: what needs the 0 to be replaced with)?

I already asked for it, but I'll repeat my previous question:

- Post a relevant example of your input file (more then just the 1 line)
- Post the desired output for the example given.
 
Old 08-02-2013, 11:07 AM   #8
Jalcock501
LQ Newbie
 
Registered: Aug 2013
Posts: 8

Original Poster
Rep: Reputation: Disabled
Search issue

Hi Guys

After working on it for while I think it's narrowed down to the way my script is searching for the mnemonic but I could be wrong here's my code so far:

Code:
#!/usr/bin/perl -w

use File::Copy;

system("clear");

my $file = "KFIREF.HEX";

print("\n\n\n\n\n\n\t\t\tSearch for Mnemonic: ");
my $mnemonic = <STDIN>;
print"\t\t\tSelect type:\n\t\t\t1: Handwritten\n\t\t\t2: Polaris\n\t\t\t3: Polaris Pilot\n\t\t\t   Selection: ";
my $input = <STDIN>;

open FILE, "<$file" || die "Can't open $file for reading - $?";
my @lines = <FILE>;
close FILE;

copy($file, "$file.bak");

my $state;
while($lines = <FILE>)
{
	if($lines =~ m/$mnemonic/){
		    if($input = '0'){substr($lines[0],74,1,0);}#Handwritten
		 elsif($input = '1'){substr($lines[0],74,1,1);}#Polaris
		 elsif($input = '2'){substr($lines[0],74,1,2);}#Polaris pilot
	}
}

system("clear");
Can anyone see why it isn't updating the file?

it should change the input file from this:

0001BOB DYLAN 14000100100100100000100101072000KFI0000007000100010N0
0
002DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

003DUMMY RECORD 14001000100107007007007001092013BSO0000230000100010N0X KW
OU 0
004DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

005DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

006DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

007DUMMY RECORD 04007300101900301901901901092013MMO1000074000100010N0SMMF
T31 0

Depending on the users selection and mnemonic search in this example (KFI) to the follow:

0001BOB DYLAN 14000100100100100000100101072000KFI0000007000100011N0
0
002DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

003DUMMY RECORD 14001000100107007007007001092013BSO0000230000100010N0X KW
OU 0
004DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

005DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

006DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

007DUMMY RECORD 04007300101900301901901901092013MMO1000074000100010N0SMMF
T31 0

Hope fully this sheds a bit more light on things.

Thanks

Last edited by Jalcock501; 08-02-2013 at 11:10 AM.
 
Old 08-02-2013, 11:53 AM   #9
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Well, I can't say I understand your question completely, but here is my attempt.

Example input file:
Code:
$ cat in 
0001BOB DYLAN 14000100100100100000100101072000KFI0000007000100010N0
0
002DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

003DUMMY RECORD 14001000100107007007007001092013BSO0000230000100010N0X KW
OU 0
004DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

005DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

006DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

007DUMMY RECORD 04007300101900301901901901092013MMO1000074000100010N0SMMF
T31 0
Code:
$ sed '/KFI/s/.\(..\)$/1\1/' in
0001BOB DYLAN 14000100100100100000100101072000KFI0000007000100011N0
0
002DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

003DUMMY RECORD 14001000100107007007007001092013BSO0000230000100010N0X KW
OU 0
004DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

005DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

006DUMMY RECORD 00000000000000000000000000000000***0000000000000000N0

007DUMMY RECORD 04007300101900301901901901092013MMO1000074000100010N0SMMF
T31 0
Hope this helps.

Last edited by firstfire; 08-02-2013 at 11:55 AM.
 
Old 08-04-2013, 06:18 AM   #10
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
1. always start with
Code:
#!/usr/bin/perl -w
use strict;
Trust me, you'll thank me later

2. you've closed the file handle 'FILE', so you can no longer read from it.
Incidentally, when opening or closing (yes, both operations) a file, best practice is to use 'or die ...' not '|| die ...'.
Its a precedence issue.


3. In any case, you then try to manipulate the in-memory array copy and never write it out to a file.

You may find these useful
http://perldoc.perl.org/
http://www.tizag.com/perlT/index.php
http://www.perlmonks.org/?node=Tutorials

Last edited by chrism01; 08-04-2013 at 06:19 AM.
 
Old 08-05-2013, 04:32 AM   #11
Jalcock501
LQ Newbie
 
Registered: Aug 2013
Posts: 8

Original Poster
Rep: Reputation: Disabled
Hi Guys

This script has a been an absolute pain! haha, right basically here is what I'm trying to do step by step:

<start user's interaction>
1. User enters Mnemonic
2. User enters amendment
<End user's interaction>

<what the script should do with the information>

3. Search on Mnemonic (entered by the user) to find matching substring (in this instance KFI) in file
4. on the same line as the mnemonic, edit the 74th character in the string to the users amendment

I've been searching, and reading everything I can but its not quite there yet. I think I need to index the line so I can amend a specific character however I am not sure. Thank you all so much for you help so far.

The script executes fine at the moment with no errors the only down side is it doesn't amend the file at all this is my code so far:

Code:
#!/usr/bin/perl -w

#use strict;
use File::Copy;

system("clear");

my $file = "KFIREF.HEX";

print("\n\n\n\n\n\n\t\t\tSearch for Mnemonic: ");
my $mnemonic = <STDIN>;
chop($mnemonic);
print"\t\t\tSelect type:\n\t\t\t1: Handwritten\n\t\t\t2: Polaris\n\t\t\t3: Polaris Pilot\n\t\t\t   Selection: ";
my $input = <STDIN>;
chop($input);

open FILE, "<$file" || die "Cannot open file";
copy($file, "$file.bak");
my @line = <FILE>;
my $handwritten = "0";
my $polaris = "1";
my $pilot = "2";

while(<FILE>)
{
	if(/$mnemonic/)
	{
		    if($input == '0'){substr($lines[0],73,1) = $handwritten;}#Handwritten
		 elsif($input == '1'){substr($lines[0],73,1) = $polaris;}#Polaris
		 elsif($input == '2'){substr($lines[0],73,1) = $pilot;}#Polaris pilot
	}
}

close FILE || die;

system("clear");
I've commented out use strict because its causing my script to bring up the following error as well:

Global symbol "@lines" requires explicit package name at ./kfiscript.pl line 28.
Global symbol "@lines" requires explicit package name at ./kfiscript.pl line 29.
Global symbol "@lines" requires explicit package name at ./kfiscript.pl line 30.

Anymore assistance would be greatly appreciated.

Thanks
 
Old 08-05-2013, 06:01 AM   #12
Jalcock501
LQ Newbie
 
Registered: Aug 2013
Posts: 8

Original Poster
Rep: Reputation: Disabled
Hi Guys

Quick update I have managed to locate the source of the issue the only problem now is that it is not updating the line.

This is the problem code
Code:
open OUTFILE, "+<$file" || die "Cannot open $file for writing - $?";
while($lines=<INFILE>)
	{
		if($lines =~ /$mnemonic/)
		{
			print $lines;
			   if($input eq "0"){substr($lines,74,1,"0");}#Handwritten
			elsif($input eq "1"){substr($lines,74,1,"1");}#Polaris
			elsif($input eq "2"){substr($lines,74,1,"2");}#Polaris pilot
			print OUTFILE $lines;
		}	
		close OUTFILE;
	}
In this snippet it gets through the while loop and into the if statement however it does not change the value of the substring that is declared.
Could some-one please help!
 
Old 08-05-2013, 10:28 AM   #13
Jalcock501
LQ Newbie
 
Registered: Aug 2013
Posts: 8

Original Poster
Rep: Reputation: Disabled
Hi Guys

I've done it! Finally. Thanks for all your help. For you who are interested in the final script here it is:

Code:
#!/usr/bin/perl -w

use strict;
use File::Copy;
use warnings;

system("clear");

my $file = "KFIREF.HEX";
if(! -s $file)
{
	print "file is empty\n";
}
else{
	copy($file, "$file.bak");
	print("\n\n\n\n\n\n\t\t\tSearch for Mnemonic: ");
	my $mnemonic = <STDIN>;
	chop($mnemonic);
	print"\t\t\tSelect type:\n\t\t\t0: Handwritten\n\t\t\t1: Polaris\n\t\t\t2: Polaris Pilot\n\t\t\t   Selection: ";
	my $input = <STDIN>;
	chop($input);

	open INFILE, "<$file.bak" || die "Cannot open $file for reading - $?";
	my $lines;
		
	open OUTFILE, ">$file" || die "Cannot open $file for writing - $?";
	
	while($lines=<INFILE>)
	{
		if($lines =~ /$mnemonic/)
		{
			print $lines;
			if($input eq "0"){substr($lines,73,1) = '0'; print OUTFILE $lines;}#Handwritten
			if($input eq "1"){substr($lines,73,1) = '1'; print OUTFILE $lines;}#Polaris
			if($input eq "2"){substr($lines,73,1) = '2'; print OUTFILE $lines;}#Polaris pilot
		}
		else
		{
			print OUTFILE $lines;
		}
		
	}
	close OUTFILE || die;
	close INFILE || die;
}
system("clear");
Thanks again guys.
 
Old 08-06-2013, 02:20 AM   #14
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
1. check success of copy() cmd
2. use 'or die', not '|| die'
3. check success of close() cmd
4. use chomp instead of chop()
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
c programming :searching a sub string in a string batman4 Programming 2 02-06-2013 05:26 PM
Replacing string. beckss Programming 9 05-22-2012 05:23 AM
[SOLVED] copy string a to string b and change string b with toupper() and count the chars beep3r Programming 3 10-22-2010 07:22 PM
Replacing certain parts of a string dipuasks Linux - Server 5 11-22-2008 07:09 AM
Searching for a string krazykow Solaris / OpenSolaris 1 03-17-2005 11:55 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:22 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration