bash: delete a string from last line

I am using a while loop to read a file and i have to delete a string from the last line. Here is the code so far:

  1. Read line by line from file new.html using while loop and store in a variable data
    2.Now, need to replace '||chr( from last line in data

I am able to replace that character from the last line of new.html, but still working on the variable data.

data=$(echo $data | sed s/||chr(/new thing/)

hi you must use sed fro this for simple way;)

sed -i '$s/chr/newchrr/' yourfile

read last line with
$s--> substitue "chr" to newchr in yourfile
-i --> edit(save) in place if you use gnu sed
or

sed '$s/chr/newchrr/' yourfile > tmpfile && mv tmpfile yourfile

regards
ygemici

@Skrynesaver:
I used
data=$(echo $data | sed s/||chr(//) -- to replace the string with empty space
and i got the following error (also tried a couple of different ways)
unexpected EOF while looking for matching `)'

I think my text was misleading - i have to replace the string '||chr( with an empty space and this has to be done only for the last line in the variable data got from the loop.

data=$(echo $data | sed 's/||chr(//')

@ygemici:

thank you for your reply, as I have already mentioned I am able to do with the file say new.html (your file). But I am not yet able to achieve it for a variable got from the while loop.
If you have a similar solution for variable instead of filename, that will be really helpful.

I tried things like below to replace the string with empty which did not work. Basically i wanted to remove that string from the last line
sed '$s/'\''||chr(9)||/ /g' data > tmpfile.txt
sed '$s/'\''||chr(9)||/ /g' $data > tmpfile.txt
sed '$s/'\''||chr(9)||/ /g' ${data} > tmpfile.txt

If you want to use variables for file names:

mInp='MyInpFile'
mOut='MyOutFile'
sed '$s/.||chr(9)||//' ${mInp} > ${mOut}
# cat infile
first line
second line
third line '||chr( do not change this ok |(*0linuxisnotunix
last linee '||chr( change this ok |(*&^%
x=`wc -l <infile`;while read -r line; do [[ $x -eq 1 ]] && newlastline=$(echo $line|sed "s;'||chr(; ;");((x--));done<infile
echo "newlastline=$newlastline"
newlastline=last linee   change this ok |(*&^%

if you update your file with new last line

# >newfile;x=`wc -l <infile`;while read -r line; do 
[[ $x -eq 1 ]]&&newlastline=$(echo $line|sed "s;'||chr(; ;")&&echo "$newlastline">>newfile||echo "$line">>newfile
((x--));done<infile;more newfile
first line
second line
third line '||chr( do not change this ok |(*0linuxisnotunix
last linee   change this ok |(*&^%

regards
ygemici

Thanks ygemici !

This works great, but I am not sure how to adapt this into my requirement as I had to manipulate it after the loop and not within. Can you also please explain the below part of the code :

sed "s;'||chr(; ;");

In my requirement I dont have a specific line number. So it will be easy if it can be manipulated after the loop is finished.

# cat infile
first line
second line
third line '||chr( do not change this ok |(*0linuxisnotunix
last linee '||chr( change this ok |(*&^%

actually , you can find with easily grep the your string which is the lines without any loop

# grep "'||chr(" infile -n|cut -d: -f1
3
4

then
you can change at 3.line your string with a space you can use this

# sed "3s;'||chr(; ;" infile

you can change at 4.line your string with a space you can use this

# sed "4s;'||chr(; ;" infile
"3s;'||chr(; ;"
//a little explanation//
" -> sed cmd begin
3s -> only edit 3 line
; -> sed exp separator
'||chr( -> your pattern
; ; --> this a space instead of your pattern (that changed with your pattern) [between semicolons]
; -> sed separator that is close sed cmd
" -> sed cmd finish (actually we tell our shell what is the sed parameters to called sed with these by shell)

@ygemici

Sorry for the late reply... i was trying a couple of other things too.. :wall:
When i tried to grep with a file name what u said below works... but it doesnt work with a variable name. Were u able to successfully execute this ? Is infile considered like a variable name ?
# grep "'||chr(" infile -n|cut -d: -f1
grep "'||chr(" new.html -n |cut -d: -f1 > new1.html works fine.

Also i did - man grep and the syntax seems to accept only file name.

With SED (accepts file and pipeline inputs), i was able to use a variable name but it wasnt able to replace the last line.. instead it replaced all lines...
This is what i used ( also tried simple examples)
name=`echo $data | sed '$s/'\''||chr(10)||/ /g'`
Expectation:
$s would replace in the last line
replace '||chr(10)|| with blank

Note: in my file there are more than one line that has that string similar to your example.

try this..

# data=`sed -n '$p' infile` ## take only last line
# name=`echo "$data" | sed '$s/'\''||chr(10)||/ /g'` ## change your pattern(s) with a space
# echo "$name" ## write your new value

regards
ygemici

@ygemici:

Thanks for your effort and time.:slight_smile:
I was working in the similar way, there were couple of glitches which i just fixed:

  1. I didnt notice that my while loop was appending extra line at the end, by which it wasnt able to replace in the last line
  2. Also the variable has to be "$var name"

My code that worked:

#here it deletes the extra line added after the while loop
var1=`echo "$data" | sed '$d'`

#here it replaces as required
Replaced_Var=`echo "$var1" | sed '$s/'\''||chr(10)||//g'`
 

I have a few questions if anyone can answer or correct me:

  1. Why is there always a line added after a while loop or when using a SED on a file or variable ? Any wise way of handling it ? Currently am deleting the last empty line
  2. With grep we can use only file names , so we cannot use variables on it
  3. With SED we can use file names or pipe-lined as my code. A variable name as such is not acceptable unless piped.