sed to remove

Hello
I have a file with records...The records have several lines and have start and end born...
This is a template:

000000001 LDR   L ^^^^^nam^^2200325Iia^45e0
000000001 022   L $$a0081-3397
000000001 041   L $$aSPA
000000001 088   L $$aJ.E.N. 551
000000001 090   L $$aINFORMES JEN
000000001 100   L $$aROMERO, L.
000000001 650   L $$aGeneral y miscelánea0
000000001 650   L $$aGeneral and miscellaneus0
000000001 FMT   L BK

LDR is start born and BK is end born...As you see, in this record I have a field 650 with L $$a string and a 0 at the end...I would liek to remove the zero in this file (34000 records) but only for the foeld 650...
Some one knows how to do?

Thanks a lot

This one will simply remove the trailing zero from every row/line, which has 650 in it's second column/field:

while read line; do
if [ $(echo $line | awk '{print $2}') = "650" ]; then
echo $line | sed 's/[034]$//'
else
echo $line
fi
done <inputfile

Is this an option for you? If not please explain why.

or try:

awk '$2==650{sub(/0$/,"")}1' infile
sed 's/\(.*650.*\)0$/\1/' file

This would work too:

sed '/650/s/0$//' infile

But sed is less precise in this case than awk, since 650 can be anywhere on the line and not necessarily in the second column.

This one is pretty "dangerous", since it will remove the trailing zero from _any_ line with 650 _anywhere_ in it. :stuck_out_tongue:

Hello
Good thanks a lot.
I see that I have some rows with "3" or "4" at the end...
No only "0", is it possible to tell script to remove all the 0 or 3 or 4 ?

Thanks a lot in advance

awk '$2==650{sub(/[034]$/,"")}1' infile

Really nice...simple code.
Thank you very much !!!!

Have a nice evening !

Cheers

 
sed 's/^\(000000001 650   L $$a.*\)0$/\1/' file

---------- Post updated at 10:43 PM ---------- Previous update was at 10:41 PM ----------

sed 's/^\(000000001 650   L $$a.*\)[0-9]$/\1/' file

Only 0 or 3 or 4

sed 's/^\(000000001 650   L $$a.*\)[034]$/\1/' problem

It's complicated to put the 00000001 in the patern,
because it's a incremental ID...Each record have a different ID...From 0000001 to 0034800

Thanks

[root@rhnserver ~]# cat myfilex
000000001 LDR   L ^^^^^nam^^2200325Iia^45e0
000000001 022   L $$a0081-3397
000000001 041   L $$aSPA
000000001 088   L $$aJ.E.N. 551
000000001 090   L $$aINFORMES JEN
000000001 100   L $$aROMERO, L.
000000001 650   L $$aGeneral y miscelánea2
000000001 650   L $$aGeneral and miscellaneus4
000000001 FMT   L BK

042347239 650   L $$aGeneral y miscelánea0
076542342 650   L $$aGeneral y miscelánea3
007657657 650   L $$aGeneral y miscelánea5
007657000 650   L $$aGeneral y miscelánea6
000080090 650   L $$aGeneral y miscelánea3
007008000 650   L $$aGeneral y miscelánea4
000002000 650   L $$aGeneral y miscelánea5
000200400 650   L $$aGeneral y miscelánea2
010030096 650   L $$aGeneral y miscelánea8
000037080 650   L $$aGeneral y miscelánea9
000006000 650   L $$aGeneral y miscelánea7
# sed -e 's/^\([0-9]* 650   L $$a.*\)[034]$/\1/' myfilex
000000001 LDR   L ^^^^^nam^^2200325Iia^45e0
000000001 022   L $$a0081-3397
000000001 041   L $$aSPA
000000001 088   L $$aJ.E.N. 551
000000001 090   L $$aINFORMES JEN
000000001 100   L $$aROMERO, L.
000000001 650   L $$aGeneral y miscelánea2
000000001 650   L $$aGeneral and miscellaneus
000000001 FMT   L BK

042347239 650   L $$aGeneral y miscelánea
076542342 650   L $$aGeneral y miscelánea
007657657 650   L $$aGeneral y miscelánea5
007657000 650   L $$aGeneral y miscelánea6
000080090 650   L $$aGeneral y miscelánea
007008000 650   L $$aGeneral y miscelánea
000002000 650   L $$aGeneral y miscelánea5
000200400 650   L $$aGeneral y miscelánea2
010030096 650   L $$aGeneral y miscelánea8
000037080 650   L $$aGeneral y miscelánea9
000006000 650   L $$aGeneral y miscelánea7

The file could also contain tab characters so a sed solution would need to test for that, e.g.

sed '/^[0-9]\{9\}[ \t]650[ \t]/s/[034]$//' infile

But since it appears to contain fixed length records and fields, this might work too:

sed '/^.\{10\}650/s/[034]$//' infile

or :slight_smile:

sed '/^[0-9]\{9\} 650/ s/[034]$//' myfile

Yes, but then you would have to test for space or tab again:

sed '/^[0-9]\{9\}[\t ]650/s/[034]$//' 

I guess there are many LDR && BK sessions, try to use this rule in code:

awk '$2=="LDR" {a=1} ($2=="650" && a=1) {sub(/[034]$/,"")} $4=="BK" {a=0}1 ' urfile

Hi
Very good
Thanks a lot, this time I have the solution !!
Great

Cheers

---------- Post updated at 05:17 AM ---------- Previous update was at 12:04 AM ----------

Hello again,

an other question about this file,
In some case I have this:

000000008 650   L $$aGeneral y miscelánea;4001
000000008 650   L $$aGeneral and miscellaneus;4001

Is it possible to rename the last number with a string? the objective is to get this:

000000008 650   L $$aGeneral y miscelánea;Quimica
000000008 650   L $$aGeneral and miscellaneus;Chemistery

THanks if you have any idea.
Cheers

I am not sure how to distinguish between the first and second line in your example - they differ only in the content of the penultimate field ("General y miscelánea" vs. "General and miscellaneus").

Based on scrutinizers solution and assuming these two are just two examples and you do not have to differentiate:

sed '/^[0-9]\{9\}[\t ]650/s/;[0-9]*$/;Quimica/'

This will change the "4001" in your example to "Quimica" in all lines having "650" in the second field.

I hope this helps.

bakunin

Hi

The only diferrence between both records is one is in spanish and the second is in english.
This is a library catalogue with references to BOOKS, so some books exists in several languages.

So if we take my exemple:

000000008 650   L $$aGeneral y miscelánea;4001
000000008 650   L $$aGeneral and miscellaneus;4001

Am other exemple (other record)

000000038 650   L $$aQu�*mica1; 4007
000000038 650   L $$aChemistry1; 4007

So I need to replace all the code after the ;
I have the correspondance for all the codes.

---------- Post updated at 06:29 AM ---------- Previous update was at 06:14 AM ----------

Hi
sorry
to be more clear, maybe I should explain the issue from the begining... :wink:

The file is a list of bib records like this:

000000001 LDR   L ^^^^^nam^^2200325Iia^45e0
000000001 022   L $$a0081-3397
000000001 041   L $$aspa
000000001 088   L $$aJ.E.N. 551
000000001 090   L $$aINFORMES JEN
000000001 650   L $$a59000;4001
000000001 FMT   L BK

As you see, LDR and FMT are the start and end of each record.
AS you see, there is a field 650 with some values.
So the objective is to replace the value in each record...by its correspondence (a string as Quimica....etc) in spanish and english.
Some of this records have fields 650 with only one value, but others have 2 values.

The results for the exemple will be:

000000001 LDR   L ^^^^^nam^^2200325Iia^45e0
000000001 022   L $$a0081-3397
000000001 041   L $$aspa
000000001 088   L $$aJ.E.N. 551
000000001 090   L $$aINFORMES JEN
000000001 650   L $$aFraseUno;FraseDos
000000001 650   L $$aStringOne;StringTwo
 000000001 FMT   L BK

This code is ok if you have only one value:

 sed -i '/[0-9]\{9\} 650   L $$a55[0-9]\{4\}/{G;s/^\(.* $$a\)[0-9]\{5\}\(.*\)\(\n\)$/\1Ciencias biom�dicas, Estudios b�sicos\2\3\1Biomedical sciences, Basic studies\2/g}' file.dat

But if I have 2 values...it do not works.
Thanks in advance

Understood. I noticed the difference, but wasn't sure if this constitutes the distinctive criterion. In your case, i presume, there is nothing left than to ad-hoc-replace the lines parts:

sed '/^[0-9]\{9\}[\t ]650/ {
                   s/\(General y miscelánea;\)[0-9]*$/\1Quimica/'
                   s/\(General and miscellaneus;\)[0-9]*$/\1Chemistry/'
                   s/\(Qu�\*mica1;\)[0-9]*$/\1<whatever-your-replacement-is>/'
                   ...
                   }' /path/to/file > /path/to/outputfile

Some caveats: probably the asterisk in "Qu�\mica1" is from differing code pages used, but generally speaking, there are some characters which have a special meaning to sed (asterisk is among them). If you want to match for such a character you will have to precede it with a backslash as escape character. To match an asterisk you will have to search for "\", not "*", like i did above.

In your second example you have whitespace between the last semicolon and the number following it ("; 4007" instead of ";4007"). If this isn't a typo you will have to change all the matching patterns like this. Notice the added space in the character range definition ("[ 0-9]" instead of "[0-9]"):

s/\(General and miscellaneus;\)[ 0-9]*$/\1Chemistry/'

I hope this helps.

bakunin