Find and Replace Different Lines

Hi, I am looking at modifiying a file but getting a bit lost with what i am trying to do.

I have the following file i need to alter. I want to search a list of files for the DEVSERIAL "0007862454" part but only the numbers. I then need to replace the line under DRIVES with the correct drive path.

NAME "Drive Name"
DESCRIPTION ""
HOST Host Name
POLICY SCSI-II
TYPE LTO-Ultrium
POOL "Default LTO-Ultrium"
LIBRARY "Library Name"
CLEANME
BUFFERS 32
DRIVES
        "/dev/rmt/s99mn"
        "49"
BLKSIZE 256
LOCKNAME  "Lock Name"
SANSTABLEADDR
DEVSERIAL "0007862454"
DEVICESUBTYPE ""
RESTOREDEVICEPOOL NO
COPYDEVICEPOOL NO

This is the script that i currently trying to play with but dont seem to be getting anywhere. I am i anywhere near the ball park on what i want to do or miles away.

for i in `drive_list`
do
   echo "Editing $i"
        awk '{ if ( $0 ~ /0007862454/ ) {
                  printf( "%s\n%s\n", "Some new inserted text here", $0 );
                  # could use the following to append
                  # printf( "%s\n%s\n", $0, "Some new appended text here" );
                } else {
                        print $0;
                }
        }' drive_list
done 

I have done one script for replacing all sysouts from my project. It may help you.
It will:

  • Print before how was it
  • Replace the needed Word alone
  • Print after how it is.
  • Print no of files changed

P.S : As sed -ie is used , a backup file with extension e will be created. So I wrote code to delete that too. I think sed -i only has to use. Anyway this script worked perfectly for me.
Take a backup of entire folder you wanna change. There is no guarantee from me.

I know this is not the right thing you asked.
Change what ever you need to.

#!/bin/bash

##########################################
#To  change System.out.println alone
##########################################


echo -e "To  change System.out.println alone `date` \n============================================================="
findString="System[ ]*.[ ]*out[ ]*.[ ]*println"
#findString="Session Destroyed"
replaceString="SomethingElse"
projectExactPath="/home/smily/ProjectPath"

echo -e "\nfindstring : $findString"
echo -e "replaceString : $replaceString"
echo -e "projectExactPath : $projectExactPath \n"

TotalNoOfFilesBefore=`find $projectExactPath -type f | wc -l`
isPresentFindNew=0
isPresentReplaceNew=0
isPresentReplace=

for filename in `find $projectExactPath -type f | grep -v "svn" | grep -E "\.java|\.jsp"`; 

do 

isPresentFind=`cat $filename | grep "$findString" | wc -l`

if [ $isPresentFind -ge "1" ] ; then

echo -e "\n\n"

echo -e "\nfilename : $filename"
echo -e "=====================================================================[>>>>>>>>"
echo -e "\n\tThe following\n---------------------------"
cat $filename | grep "$findString"

echo "Before : $isPresentFindNew"
isPresentFindNew=`echo "$isPresentFind + $isPresentFindNew" | bc`
echo "After : $isPresentFindNew"

echo "Replace command.........."
#################################REPLACE COMMAND#####################################
sed -ie "s/${findString}/${replaceString}/g" $filename
#################################REPLACE COMMAND#####################################

echo -e "\n\tChanged to : \n------------------------" 
cat $filename | grep "$replaceString"
echo -e "\n====================================================================<<<<<<<<]"

tempFile=$filename"e"
tempFilee=$filename"ee"
[ -f $tempFile ] && echo -e "\nDeleting \n$tempFile" && rm $filename"e" -f && echo "deleted"
[ -f $tempFilee ] && echo -e "\nDeleting \n$tempFilee" && rm $tempFilee -f && echo "deleted"
echo -e "\n\n"



isPresentReplace=`cat $filename | grep "$replaceString" | wc -l`
echo "Before : $isPresentReplaceNew"
isPresentReplaceNew=`echo "$isPresentReplace + $isPresentReplaceNew" | bc`
echo "After : $isPresentReplaceNew"

fi

done

TotalNoOfFilesAfter=`find $projectExactPath -type f | wc -l`

#Both should be same
echo -e "TotalNoOfFilesBefore Running script : $TotalNoOfFilesBefore"
echo -e "TotalNoOfFilesAfter Running Script  : $TotalNoOfFilesAfter"

echo -e "\n$findString is present or not [total=]: $isPresentFindNew"
echo -e "\n$replaceString is present or not [total=]: $isPresentReplaceNew"
echo -e "\n\n"

.

Try this from within the directory your files are in:

 grep -l '0007862454' ./* | xargs awk '/DRIVES/{a=NR+1} a==NR{$0=FILENAME}{print > FILENAME".new"}'
1 Like

I have now got that command working via command line perfectly. I just need to sort out the rest so that it uses variable to bring in the changes. Thank you for your help.

Now i understand the need to for the -v which is to allow in the variables. You just answered the question i was going to ask.

Been a great help. Spend many hours trying to work this out. So simple when you know how.

If I understand you correctly, you want to specify the value to insert after DRIVES. Try this:

z="TEST"
grep -l '0007862454' ./* | xargs awk -v newDrive=$z '/DRIVES/{a=NR+1} a==NR{$0=newDrive}{print > FILENAME".new"}'

Then in your script, just set newDrive to any variable you have defined.

1 Like

Sorry... posted in a wrong thread...

Thanks all for ur replies, I solved the issue with the below command..

perl -i -ne 's;(\x1F)0\n;\x1F0�\n;g;print;' $rejectwoheader

It works how i want now but i need to get the file to overwrite the original file.

I tried using && FILENAME".new" FILENAME but i get error at the end of the awk command.

 syntax error The source line is 1.
 The error context is
                /DRIVES/{a=NR+1} a==NR{$0="        "new_drive_path}{print > FILENAME".new"} >>>  && <<< 
while read line
do
        DRIVE_PATH=`echo "$line" | awk '{print $4}' | cut -c 2-20 | sed -e 's/\(.*\).$/\1/g`
        DRIVE_SERIAL=` echo "$line" | awk '{print $6}' | cut -c 2-11`
        grep -l "$DRIVE_SERIAL" ./* | xargs awk -v new_drive_path=$DRIVE_PATH '/DRIVES/{a=NR+1}
 a==NR{$0="        "new_drive_path}{print > FILENAME".new"}'                             
done < $DRIVESERIALANDPATHFILE

I don't believe you can overwrite the original file without causing a problem. Although this did work for me:

{print > FILENAME}

But to be safe, you can move the new file to the old file after awk has finished. So after the print block append:

END{system("mv "FILENAME".new "FILENAME)}

So for your code:

grep -l "$DRIVE_SERIAL" ./* | xargs awk -v new_drive_path=$DRIVE_PATH '/DRIVES/{a=NR+1}
 a==NR{$0="        "new_drive_path}{print > FILENAME".new"}END{system("mv "FILENAME".new "FILENAME)}'