Convert Overpunch character values to number that comes between the numbers in perl

I have variable that contains multiple values of number and also includeOverpunch character so we want to replace it with numbers.
here are the example:

11500#.0#
28575$.5$
527#.7#
42".2"
2794 .4
2279!.9!
1067&.7&
926#.6#
2279!.9!
885".5"
11714$.4$
27361'.1'
2%.2%
533".3"

could you please help me out.

What have you tried so far?

I used ord function but it is working for single special character.not able to covert above value.

It looks like you need to add 16 to the ascii value of each special character.
That is assuming that a space is zero, and a ) is 9.
In pseudo code

a=input string
for i=1 to len(a)
if asc(substr(a,i,1)) <48
  echo chr(asc(substr(a,i,1)+16)
else
  echo substr(a,i,1)
fi
next i

where asc("0") is 48 and chr(48) is "0".
Slight adjustment, a decimal point is 46 so line 3 should be <46 not <48

Hi jgt- It didnt work, I want to change ascii character to number that is between the numbers in all rows.

11500#.0#
28575$.5$

PHP has the chr and ord (asc) functions.
What did you write?

jgt- I am working with perl on linux env. we can convert single value with the help of .

$ascii_value = ord("%");
print 'cii_value'.$ascii_value;

it print: cii_value37
but i need to find and replace a column value that can different ascii values. so in this it is not working.
like-- $ascii_value = ord("886%.6%"); then output : 56
but i need 88637.637 -- this correct. Please help on this

I showed you how to do that. Read the input as a string, and examine each character in the string using substrings, and if the character has an ord() value less then 46, convert the character to the chr (ord()+16). Then output the string one character at a time, or create a new string to process.

i tried the give loop by jgt but it is not working in unix and perl

What jgt posted was pseudocode, not actual code. Pseudocode is used to demonstrate coding principles

I don't code much in perl , but this seems to do what you want using awk :

awk '
BEGIN {	a = "\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27" \
	    "\30\31\32\33\34\35\36\37 !\"#$%&\47()*+,-./0123456789:;<=>?" \
	    "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz" \
	    "{|}~\177"
}
{	printf("Processing:%s--->", $0)
	for(i = 1; i <= length($0); i++)
		if((c = substr($0, i, 1)) ~ /[0-9.]/)
			printf("%s", c)
		else	printf("%d", index(a, c))
	print ""
}' file

which, if file contains the sample input you provided in post #1 in this thread, produces the output:

Processing:11500#.0#--->1150035.035
Processing:28575$.5$--->2857536.536
Processing:527#.7#--->52735.735
Processing:42".2"--->4234.234
Processing:2794 .4--->279432.4
Processing:2279!.9!--->227933.933
Processing:1067&.7&--->106738.738
Processing:926#.6#--->92635.635
Processing:2279!.9!--->227933.933
Processing:885".5"--->88534.534
Processing:11714$.4$--->1171436.436
Processing:27361'.1'--->2736139.139
Processing:2%.2%--->237.237
Processing:533".3"--->53334.334

As always, if someone wants to try this on a Solaris/SunOS system, change awk to /usr/xpg4/bin/awk or nawk .

Please, someone enlighten me: WHAT is an "overpunch character"?

1 Like

Found this:
https://en.wikipedia.org/wiki/Punched\_card\#IBM\_80-column\_punched\_card\_formats\_and\_character_codes
and

1 Like

Thanks, should have searched myself. That's not the way the term is used in here, no?

Great answer don !! but can u please tell how we can pass variable one by one into this command instead of passing file.

Hi RudiC and Scrutinizer,
Using the term overpunch, I first thought of Hollerith cards as well. Then I assumed that nadeemrafikhan was referring to characters that appear on the numeric keys on the keyboard with the shift key held down:

)!@#$%^&*(  <- Characters on shifted numeric keys
0123456789  <- Characters on numeric keys

but the <single-quote> and <double-quote> characters don't fit that pattern either.

Hi nadeemrafikhan,
What do you mean by "overpunch character"?

Perhaps you want something like:

#!/bin/ksh
while read -r input
do	result=$(printf '%s\n' "$input" | awk '
	BEGIN {	a = "\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17" \
		    "\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37" \
		    " !\"#$%&\47()*+,-./0123456789:;<=>?@" \
		    "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \
		    "abcdefghijklmnopqrstuvwxyz{|}~\177"
	}
	{	for(i = 1; i <= length($0); i++)
			if((c = substr($0, i, 1)) ~ /[0-9.]/)
				printf("%s", c)
			else	printf("%d", index(a, c))
		print ""
	}')
	printf 'Processing:%s-->%s\n' "$input" "$result"
done < file

which, when run by a POSIX-conforming shell, produces exactly the same output as my earlier suggestion, but runs slower and consumes more system resources.

Well, I thought of old printers: print a char, backspace, overpunch, but that was mayhap a vocabulary problem...

That's different depending on the local keyboard type. German kbd:

 ! " � $ % & / ( ) = 
 1 2 3 4 5 6 7 8 9 0 

BTW, that's part of the problem we (I !) non-ascii people have quick typing some *nix standard chars like / , | , and \ .

Thanks again Don , but still it pending :frowning:
let me show you how I am doing it.
I have this data
0002178#
0001008(
0000886%
and I know what would be the overpunch character because i extract it from substr function.

if ($f !~ /^\d+$/ )
{
$camount=substr($line,23,8);--this is the vulue like 0002178,0001008,0000886
$vovrpunch=ord("$f");  --- getting the overpunch value but it is sending me wrong
$var3 = $camount.$vovrpunch;
$ltwodgt = substr($var3,-2);
$var3 =~ s/\d{2}$//;
$camnt=$var3.".".$ltwodgt;
$camnt =~ s/^0+//;
#print "$damnt\n";
}

value that are coming:
2178.35
1008.40
886.37

but the correct values are:

217.83
100.88
88.65

Could you please help me on this :frowning:

number=`echo $string |sed -e script`

#where script is

 
s/ /0/g
s/\!/1/g
s/\"/2/g
s/\#/3/g
s/\$/4/g
s/\%/5/g
s/\&/6/g
s/\'/7/g
s/\(/8/g
s/\)/9/g

Somehow some of the digits in the input have been changed to characters 16 ascii positions lower in the character set.

---------- Post updated at 01:01 PM ---------- Previous update was at 12:53 PM ----------

Think of it as a Florida election where some of the chad stays in row 4 in 8 channel paper tape.