[awk] Math & Bold-Font?

Heya

There is a script which has presets stored in a tab-seperated file.
That script also has $help_text , which will be shown when called with invalid arguments or -h .
So i do need to have that file ready, so the help text can get the values out of the file, and print it with the $help_text .
That works, but i wonder if there is a way to do this with awk, as figured, it seems quite fast and power full, but until now i failed to see actual use for me.

How the relevant code parts look at the moment:

PRESETS=$CONFIG_DIR/presets
BOLD="\033[1m"
RESET="\033[0m"
UNDERLINE="\033[4m"
#
#	Check for PRESETS, required for proper help display
#
	WritePresetFile() { #
        # Write a basic table of the presets
        # 
	cat > "$PRESETS" << EOF
# Label	Resolution 	Pixels	Vidbit	Audbit	Bitrate	1min	Comment
# Label	Resolution 	Vidbit	Audbit	1min	Comment	 #--># This is for your orientation, the above is to display
scrn	resolve 	1024	192	?	This is only used for screenrecording
qvga	  320x240	240	128	2.8mb	Quarter of VGA, mobile devices 
hvga	  480x320	320	128	3.3mb	Half VGA, mobile devices
nhd	  640x360	512	192	5.2mb	Ninth of HD, mobile devices
vga	  640x480	640	192	6.1mb	VGA
a-vga	  640x480	512	192	5.2mb	VGA, optimized for anime cartoons
wvga	  768x480	768	192	7.6mb	Wide VGA
dvd	  720x480	720	256	7.2mb	DVD - PAL
wdvd	  720x576	800	256	7.7mb	DVD-wide - Pal
fwvga	  854x480	768	256	7.5mb	DVD-wide - NTCS, mobile devices
hd	 1280x720	1024	384	10.1mb	HD aka HD Ready
a-hd	 1280x720	768	384	8.5mb	HD, optimized for anime cartoons
fhd	1920x1080	1792	384	16.7mb	Full HD
a-fhd	1920x1080	1280	256	12.4mb	Full HD, optimized for anime cartoons
qhd	2560x1440	3072	448	26.9mb	Quad HD - 4xHD
uhd	3840x2160	5120	512	43.4mb	4K, Ultra HD TV
EOF
	}
	[ -f "$PRESETS" ] || \
		WritePresetFile
#
# The whole subshell is what i currently use.
#
# help_text=" .....
# ...
$( 
        printf "\t$UNDERLINE ";$SED s,"#",, "$PRESETS" | $GREP Pix
	printf "$TUI_RESET"
	$GREP -v Audbit "$PRESETS" | \
		while read label res vidbit audbit siz comment
		do
			if [ ! $label = scrn ]
			then	pixels=$[ ${res/x*/} * ${res/*x/} ]
			#	[ ${#pixels} -gt 9 ] && \
			#		dot=${pixels:0:( - 8 )} && \
			#		pixels="${pixels:0:(-9)}.${dot:0:1}bil"
			#	[ ${#pixels} -gt 6 ] && \
			#		dot=${pixels:0:( - 5 )} && \
			#		pixels="${pixels:0:(-6)}.${dot:0:1}mil"
				#[ $pixels -eq 0 ] && pixels="0     "
				if [ ${#pixels} -gt 6 ]
				then	dot_cut=5
					cut=6
					ext=mil
				elif [ ${#pixels} -ge 4 ]
				then	dot_cut=2
					cut=3
					ext=k
				elif [ ${#pixels} -le 3 ]
				then	dot_cut=""
					cut=""
					ext=""
				fi
				[ ! -z "$dot_cut" ] && \
					dot="${pixels:0:(-$dot_cut )}" && \
					pixels="${pixels:0:(-$cut)}.${dot:0:1}$ext" || \
					pixels="${pixels}$ext"

				bitrate=$[ $vidbit + $audbit ]
				#echo ${#bitrate} $bitrate
				if [ ${#bitrate} -gt 6 ]
				then	dot_cut=5
					cut=6
					ext=gb
				elif [ ${#bitrate} -ge 4 ]
				then	dot_cut=2
					cut=3
					ext=mb
				elif [ ${#bitrate} -le 3 ]
				then	dot_cut=""
					cut=""
					ext=kb
				fi

				[ HD = "${comment:0:2}" ] && \
					comment="${BOLD}HD${RESET}${comment:2}"
				[ ! -z "$dot_cut" ] && \
					dot="${bitrate:0:( - $dot_cut )}" && \
					bitrate="${bitrate:0:(-$cut)}.${dot:(${#dot} - 1):1}$ext" || \
					bitrate="${bitrate}$ext"

				printf "\t* ${BOLD}$label${RESET}\t$res \t$pixels\t$vidbit\t$audbit\t~$bitrate\t$siz\t$comment\n"
			fi
		done
)
"

Which then should output like:

	  Label	Resolution 	Pixels	Vidbit	Audbit	Bitrate	1min	Comment
	* qvga	320x240 	76.7k	240	128	~368kb	2.8mb	Quarter of VGA, mobile devices
	* hvga	480x320 	153.1k	320	128	~448kb	3.3mb	Half VGA, mobile devices
	* nhd	640x360 	230.2k	512	192	~704kb	5.2mb	Ninth of HD, mobile devices
	* vga	640x480 	307.3k	640	192	~832kb	6.1mb	VGA
	* a-vga	640x480 	307.3k	512	192	~704kb	5.2mb	VGA, optimized for anime cartoons
	* wvga	768x480 	368.3k	768	192	~960kb	7.6mb	Wide VGA
	* dvd	720x480 	345.3k	720	256	~976kb	7.2mb	DVD - PAL
	* wdvd	720x576 	414.4k	800	256	~1.0mb	7.7mb	DVD-wide - Pal
	* fwvga	854x480 	409.4k	768	256	~1.0mb	7.5mb	DVD-wide - NTCS, mobile devices
	* hd	1280x720 	921.9k	1024	384	~1.4mb	10.1mb	HD aka HD Ready
	* a-hd	1280x720 	921.9k	768	384	~1.1mb	8.5mb	HD, optimized for anime cartoons
	* fhd	1920x1080 	2.2mil	1792	384	~2.1mb	16.7mb	Full HD
	* a-fhd	1920x1080 	2.2mil	1280	256	~1.5mb	12.4mb	Full HD, optimized for anime cartoons
	* qhd	2560x1440 	3.3mil	3072	448	~3.5mb	26.9mb	Quad HD - 4xHD
	* uhd	3840x2160 	8.8mil	5120	512	~5.6mb	43.4mb	4K, Ultra HD TV

The bold HD in the comments are absolute optional, but a nice to have.

What i have so far:
(actualy had a better code last night, but since i failed with the bold thing, i just kept the above solution.)

	$GREP -v "#" "$PRESETS" | $AWK '{ 
		bitrate=$3+$4
		#pixels =${2/x*/} * ${2/*x/}   # When enabling this, i get no output at all -- seems substitution works diffrently for colums.
		print "\t* $BOLD"$1"$RESET\t"$2"\t"pixels"\t"$3"\t"$4"\t"bitrate"\t"$5"\t"$6
	}'

Which looks like:

	  Label	Resolution 	Pixels	Vidbit	Audbit	Bitrate	1min	Comment
	* ${BOLD}scrn$RESET	resolve		1024	192	1216	?	This
	* ${BOLD}qvga$RESET	320x240		240	128	368	2.8mb	Quarter
	* ${BOLD}hvga$RESET	480x320		320	128	448	3.3mb	Half
	* ${BOLD}nhd$RESET	640x360		512	192	704	5.2mb	Ninth
	* ${BOLD}vga$RESET	640x480		640	192	832	6.1mb	VGA
	* ${BOLD}a-vga$RESET	640x480		512	192	704	5.2mb	VGA,
	* ${BOLD}wvga$RESET	768x480		768	192	960	7.6mb	Wide
	* ${BOLD}dvd$RESET	720x480		720	256	976	7.2mb	DVD
	* ${BOLD}wdvd$RESET	720x576		800	256	1056	7.7mb	DVD-wide
	* ${BOLD}fwvga$RESET	854x480		768	256	1024	7.5mb	DVD-wide
	* ${BOLD}hd$RESET	1280x720		1024	384	1408	10.1mb	HD
	* ${BOLD}a-hd$RESET	1280x720		768	256	1024	8.5mb	HD,
	* ${BOLD}fhd$RESET	1920x1080		1792	384	2176	16.7mb	Full
	* ${BOLD}a-fhd$RESET	1920x1080		1280	256	1536	12.4mb	Full
	* ${BOLD}qhd$RESET	2560x1440		3072	448	3520	26.9mb	Quad
	* ${BOLD}uhd$RESET	3840x2160		5120	512	5632	43.4mb	4K,

First question, can i make bold text with awk print?
Second question, is about the math and substitution, i've seen that gsub be used, but i fail to understand - how.

Using an example from another thread:

'{x=substr($0,N+1); gsub(".","*",x); print substr($0,1,N) x}' N=3

I get the feeling, somehow awk reads from right to left, rather then left to right, like bash.
Anyway, as last N gets set to 3, so substr can subtract it on print, but what is that 1 and $0 (colum 0, does that mean the whole line?) doing there?
Also on the first x=substr, again column 0... and N gets increased to 4??
:confused:

Third question, how do i get the rest of the comments displayed?

Thank you

awk is not shell. It does not have shell variables or shell substitutions. If you want shell variables in awk, you have to put them there. If you want substitutions, you'll have to use awk's.

$ means column in awk. That's why $1 gets you column one. Variables are just strings, like VAR=1 . You can use an expression as a column number too, like print $(VAR+1) for column 2.

So, to get your variables, into awk, you will have to put them into awk.

awk -v VAR1="value1" -v VAR2="value2" ... '{ code }' filenames

Or the more old-fashioned

awk '{code}' VAR1="value1" VAR2="value2" filename

To get pixels, in awk code, I'd do this:

split($2, A, "x");
pixels=A[0] * A[1];

Also, doing grep | grep | grep | awk is pointless when it's that easy to just put it all in awk. You can replace this:

grep -v "^#" filename | awk '{ ... }'

with:

awk '/^#/ { next } { ... }' filename
1 Like

Hi, shell variables need to be passed to awk in a different way, for example:
awk -v bold="$BOLD" -v rst="$RESET"
The variable can then be accessed as bold and rst

I would try something like this (not tested):

$AWK '{ 
		bitrate=$3+$4
		# pixels =${2/x*/} * ${2/*x/}   # When enabling this, i get no output at all -- seems substitution works diffrently for colums. This will not work, parameter expansion is a shell feature, this is awk
		print "\t* " bold $1 rst, $2, pixels,$3,$4,bitrate,$5,$6
	}' OFS='\t'
1 Like

To get this right:
Split takes column 2, splits the string at the x's and saves its output in an array(like) variable for later usage.
Sadly, pixels get calculated to 0 :frowning: but the bold text is working, thank you. :slight_smile:

I'm now stuck at further parsing of bitrates, i'd like to put a 'kb' at its end as long bitrates do not exceed 1mb, then 'mb' should be appended.

	$AWK '/^#/ { next } ;
	{ 
		bitrate=$3+$4;
		switch (length(bitrates)) {
			case >=4:
				ext=mb
			default:
				ext=kb
		}
		
		split($2, A, "x");
		pixels=A[0] * A[1];
		print "\t* "BOLD$1RESET"\t"$2"\t"pixels"\t"$3"\t"$4"\t"bitrate""ext"\t"$5"\t"$6;
	}' BOLD="\033[1m" RESET="\033[0m" UNDERLINE="\033[4m" "$PRESETS"

But this doesnt show any output at all :frowning:

Thank you in advance

EDIT:
So with Scrutinizer's suggestion, and commented out the switch block,

$AWK '/^#/ { next } ;
	{ 
		bitrate=$3+$4;
		#switch (length(bitrates)) {
		#	case >=4:
		#		ext=mb
		#	default:
		#		ext=kb
		#}
		
		split($2, A, "x");
		pixels=A[0] * A[1];
		print "\t* "BOLD$1RESET,$2 "   ",pixels,$3,$4,bitrate ext,$5,$6;
	}' BOLD="\033[1m" RESET="\033[0m" UNDERLINE="\033[4m" OFS="\t" "$PRESETS"

i get this:

	  Label	Resolution 	Pixels	Vidbit	Audbit	Bitrate	1min	Comment
	* scrn	resolve   	0	1024	192	1216	?	This
	* qvga	320x240   	0	240	128	368	2.8mb	Quarter
	* hvga	480x320   	0	320	128	448	3.3mb	Half
	* nhd	640x360   	0	512	192	704	5.2mb	Ninth
	* vga	640x480   	0	640	192	832	6.1mb	VGA
	* a-vga	640x480   	0	512	192	704	5.2mb	VGA,
	* wvga	768x480   	0	768	192	960	7.6mb	Wide
	* dvd	720x480   	0	720	256	976	7.2mb	DVD
	* wdvd	720x576   	0	800	256	1056	7.7mb	DVD-wide
	* fwvga	854x480   	0	768	256	1024	7.5mb	DVD-wide
	* hd	1280x720   	0	1024	384	1408	10.1mb	HD
	* a-hd	1280x720   	0	768	256	1024	8.5mb	HD,
	* fhd	1920x1080   	0	1792	384	2176	16.7mb	Full
	* a-fhd	1920x1080   	0	1280	256	1536	12.4mb	Full
	* qhd	2560x1440   	0	3072	448	3520	26.9mb	Quad
	* uhd	3840x2160   	0	5120	512	5632	43.4mb	4K,

Regarding the comments, do i need to have to blindly append columns after $6, so all the words of any possible comments become shown?

Thank you

I don't think you can do 'case >= 4'.

Also, ext=mb sets ext to blank unless mb happens to be set to something. I think you meant ext="mb"

Try: ext="kb" ; if(value >= 4) ext="mb";

Also, print "BOLD$1RESET" will print the literal words BOLD and RESET and the literal text $1. awk really is a different language than shell, it doesn't substitute inside quotes -- in fact it doesn't substitute, at all, ever. If you want the variables, do print BOLD $1 RESET

Lastly, and most importantly, you forgot to give awk a filename.

1 Like

Sadly, setting / comparing with value seems to be an issue for my approach:

	$AWK '/^#/ { next } ;
	{ 
		bitrate=$3+$4;
		len=( length(bitrates) ); print len
		len = length(bitrates)  ; print len
		ext="kb"; if(len >= 4) ext="mb"; 
		if(len >= 4) bitrates=(substr(bitrates,3));

		split($2, A, "x");
		pixels=A[0] * A[1];
		
		print "\t* "BOLD$1RESET,$2 "   ",pixels,$3,$4,bitrate ext,$5,$6" "$7" "$8" "$9" "$10" "$11" "$12" "$13" "$14" "$15;
		
	}' BOLD="\033[1m" RESET="\033[0m" UNDERLINE="\033[4m" OFS="\t" "$PRESETS"
  1. While i do see now 'kb' for all the bitrates, it neither changes to mb when bitrate is 5120, nor does it cut 3 numbers from the string.
  2. Is there a better way o display the whole comment, rather than " "$7" "$8" "$9" "$10" "$11" "$12" "$13" "$14" "$15 to preseve words?
  3. pixels are still empty, and would require the same 'handling' as the bitrates.

len is always 0, so that is why the check doesnt work, but how to fix that please?

Thank you

Garbage in, garbage out. What are you passing into length?

I see bitrate used in some places, bitrates in others.

1 Like

If you want 5120 kb to be displayed as 5 MB, bitrates=(substr(bitrates,3) would yield "20" which should not be considered a correct value. Use substr (bitrates,1,1) , or, even better, bitrates/=1024 .

---------- Post updated at 21:07 ---------- Previous update was at 20:56 ----------

Would this do what you want:

{bitrate=$3+$4
ext=bitrate >= 1024 ?"MB":"kB"
bitrate/=bitrate >= 1024 ?1024:1}
1 Like

Ok, so far so good, still stuck with if blocks...

4 Awk If Statement Examples ( if, if else, if else if, :? )
The AWK Manual - String Functions (guess this doesnt work because of nawk != awk)
But even when starting with the 'awk' manual, i end up: The GNU Awk User :confused:

	$AWK '/^#/ { next } ; 
	/^scrn/ { next } ;
	{ 
		bext="kb";
		bitrates=$3+$4;
		len=( length(bitrates) );
		if(len >= 4) 
			ext="mb"
			cut=len-3
			bitrates=substr(bitrates,1,cut);
			
		split($2, A, "x");
		pext="k";
		pixels=A[1] * A[2];
		len=( length(pixels) );
	#	if(len >= 7 )
	#		ext="bil"
	#		cut=len-6
	#		pixels=substr(pixels,1,cut);
	#	else
			if(len >= 4)
				ext="mil"
				cut=len-3
				pixels=substr(pixels,1,cut);
		
		print "\t* "BOLD$1RESET,$2 "   ",pixels pext,$3,$4,"~" bitrates bext,$5,$6" "$7" "$8" "$9" "$10" "$11" "$12" "$13" "$14" "$15;
		
	}' BOLD="\033[1m" RESET="\033[0m" UNDERLINE="\033[4m" OFS="\t" "$PRESETS"

Prints out as:

	  Label	Resolution 	Pixels	Vidbit	Audbit	Bitrate	1min	Comment
	* qvga	320x240   	76k	240	128	~kb	2.8mb	Quarter of VGA, mobile devices     
	* hvga	480x320   	153k	320	128	~kb	3.3mb	Half VGA, mobile devices      
	* nhd	640x360   	230k	512	192	~kb	5.2mb	Ninth of HD, mobile devices     
	* vga	640x480   	307k	640	192	~kb	6.1mb	VGA         
	* a-vga	640x480   	307k	512	192	~kb	5.2mb	VGA, optimized for anime cartoons     
	* wvga	768x480   	368k	768	192	~kb	7.6mb	Wide VGA        
	* dvd	720x480   	345k	720	256	~kb	7.2mb	DVD - PAL       
	* wdvd	720x576   	414k	800	256	~1kb	7.7mb	DVD-wide - Pal       
	* fwvga	854x480   	409k	768	256	~1kb	7.5mb	DVD-wide - NTCS, mobile devices     
	* hd	1280x720   	921k	1024	384	~1kb	10.1mb	HD aka HD Ready      
	* a-hd	1280x720   	921k	768	256	~1kb	8.5mb	HD, optimized for anime cartoons     
	* fhd	1920x1080   	2073k	1792	384	~2kb	16.7mb	Full HD        
	* a-fhd	1920x1080   	2073k	1280	256	~1kb	12.4mb	Full HD, optimized for anime cartoons    
	* qhd	2560x1440   	3686k	3072	448	~3kb	26.9mb	Quad HD - 4xHD      
	* uhd	3840x2160   	8294k	5120	512	~5kb	43.4mb	4K, Ultra HD TV  

What confuses me is the diffrence between the pixel and bitrate columns - allthough the 'producing' codeblock is identical.

It should only cut off 3 numbers when there are at least 4 numbers, for the pixels it doesnt work, as in when i uncomment those lines checking for 'bil' values, it wont print any output at all.
And regarding the bitrate, i seem to not check it properly, what am i doing wrong?

Thank you

---------- Post updated at 21:44 ---------- Previous update was at 21:34 ----------

What i try to say/achieve:
All the highlighted k(b)'s should be m(b)'s.
The red ~ should be followed by 3 numbers for kb, and 'all' the megabyte number and followed by the mb string for numbers within that range.

---------- Post updated at 21:53 ---------- Previous update was at 21:44 ----------

@ RudiC, so focused on cutting of number of chars, that i forgot to do the math :slight_smile:
However, i would need to limit the amount of decimals after the dot.
Output example:

# RAW: 0.359375
~0.359375mb

Desired:

# RAW: 0.3
# RAW: 10.0 ## or just 10
~0.3mb
~10.0mb

And since i already have problems cutting the right position of a integer number, i'm clueless where to start for this one.

Thank you

1) You print bext but assign "mb" to ext .
2) awk 's if needs {...} around a compound statement; your snippet executes ext="mb" only if len>=4 , but cut= etc for every line.
3) cf. formatted printf to do some rounding on decimal places.

1 Like

Its working now as expected, thank you guys.
Got any improvement suggestions?

	$AWK '/^#/ { next } ; 
	/^scrn/ { next } ;
	{ 
		bext="kb";
		pext="k";
		
	# Bitrates
		bitrates=$3+$4;
		len=( length(bitrates) );
		if(len >= 4) {
			bext="mb"
			bitrates/=1024
		}
		split(bitrates, B, ".");
		bitrates=B[1] ;
		dots=B[2];
		if (dots == "") { dots="" } else { dots="."dots }
		
	# Pixels
		split($2, A, "x");
		pixels=A[1] * A[2];
		len=( length(pixels) );
		if(len >= 7 ) {
			pext="mil"
			cut=len-6
			#pixels=substr(pixels,1,cut);
			pixels=pixels / 1000 / 1000
		} else {
			if(len >= 4) {
				pext="k"
				cut=len-3
				#pixels=substr(pixels,1,cut);
				pixels/=1000
			}
		}
		split(pixels, P, ".");
		pix=P[1] ;
		pots=P[2];
		if (pots == "") { pots="" } else { pots="."pots }
		
	# Output
		print "\t* "BOLD$1RESET,$2 "   ",pix substr(pots,1,2) pext,$3,$4,"~" bitrates substr(dots,1,2) bext,$5,$6" "$7" "$8" "$9" "$10" "$11
		
	}' BOLD="\033[1m" RESET="\033[0m" OFS="\t" "$PRESETS"

One last thing, the calculation is a bit weird... see screenshot (wide).
They both refer to this calculated amount of pixels, but get diffrent end values, eventhough i initialy try the same approach.

	76800	
	153600	
	230400	
	307200	
	307200	
	368640	
	345600	
	414720	
	409920	
	921600	
	921600	
	2073600	
	2073600	
	3686400	
	8294400

Any ideas?
Thank you and have a good weekend :slight_smile:

LOOL scratch that, figured i did the left script (original) shown with wrong cutting...
/solved & good night :slight_smile:

---------- Post updated at 00:19 ---------- Previous update was at 00:19 ----------

LOOL scratch that, figured i did the left script (original) shown with wrong cutting...
/solved & good night :slight_smile:

Well, hmmm, I'm not sure I understand what you're doing up there ... mayhap you want to look into this one:

awk     'BEGIN  {split ("B kB MB GB", UNT)
                 ln10=log(10)
                 print "          Label Resolution      Pixels             Vidbit Audbit  Bitrate 1min    Comment"
                }
         NR==1 ||
         /^#/ ||
         /^scrn/ { next } ;

        {
        # Bitrates
                TMP=$3+$4;
                XP=int(log(TMP)/ln10/3)
                bitrate = sprintf ("%.2f", TMP / 10^(3*XP))
                bUNT=UNT[1+XP]
                
        # Pixels
                split($2, A, "x");
                TMP=A[1] * A[2];  
                XP=int(log(TMP)/ln10/3)
                pixels = sprintf("%.2f", TMP / 10^(3*XP))
                pUNT = UNT[1+XP]
 
        # Output
                print "\t* "BOLD$1RESET,$2 "   ",pixels pUNT , $3, $4, "~" bitrate bUNT, $5, $6" "$7" "$8" "$9" "$10" "$11
                
        }' BOLD="\033[1m" RESET="\033[0m" OFS="\t" file
     Label    Resolution    Pixels   Vidbit    Audbit    Bitrate    1min    Comment
    * qvga    320x240        76.80kB    240    128    ~368.00B    ~kb    2.8mb Quarter of VGA, mobile devices
    * hvga    480x320       153.60kB    320    128    ~448.00B    ~kb    3.3mb Half VGA, mobile devices 
    * nhd     640x360       230.40kB    512    192    ~704.00B    ~kb    5.2mb Ninth of HD, mobile devices
    * vga     640x480       307.20kB    640    192    ~832.00B    ~kb    6.1mb VGA 
    * a-hd   1280x720       921.60kB    768    256    ~1.02kB    ~1kb    8.5mb HD, optimized for anime cartoons
    * fhd   1920x1080       2.07MB     1792    384    ~2.18kB    ~2kb    16.7mb Full HD   
    * a-fhd 1920x1080       2.07MB     1280    256    ~1.54kB    ~1kb    12.4mb Full HD, optimized for anime
   

Units may have to be adapted as well as <TAB>s, but anyway... might be worthwhile?

---------- Post updated at 15:20 ---------- Previous update was at 14:56 ----------

Or even

awk     'BEGIN  {split ("B kB MB GB", BUNT)
                 split ("p kp Mp Gp", PUNT)
                 ln10=log(10)
                 print "          Label Resolution      Pixels          Vidbit  Audbit  Bitrate 1min    Comment"
                }

         function FMT(NBR, U)
                {XP=int(log(NBR)/ln10/3)
                 return sprintf ("%.2f %s", NBR / 10^(3*XP), U[1+XP])
                }

         NR==1 ||
         /^#/ ||
         /^scrn/ { next } ;

        {
        # Bitrates
                bitrate = FMT($3+$4, BUNT);

        # Pixels
                split($2, A, "x");
                pixels = FMT(A[1] * A[2], PUNT);

        # Output
1 Like

Thank you Rudic, that is something to study on monday :slight_smile:
The above is my - obviously with help - first awk 'script'.

So by the time i really got annoyed by the attempt to substr the proper number of chars of the numbers, to print 1 or 2 decimals (couldnt decide) after the dot, and the dot only if required there were uneven numbers.
So i came up with a solution using methods i knew or just learned and did the job i wanted :slight_smile:

Since i had problems to get the amount of full numbers before the dot, to the remove them and the dot, to just use the first (two) char/s then to display, i used split to get full and uneven (decimal) numbers and did just the same, with the 'extracted' string in the array.

Have a good weekend :slight_smile:

Thank you RudiC for the updated code, sadly, one cant double thank in such situations.

So what i have now is this, with these questions:

	ln10=log(10)	# What is this for?
	#print ln10	## 2.30259

Really, i can make no sense of it, maybe i'm too focused on the number?

	# Again what for is ln10 used here and XP prepared for? And what is done anwyay?
	XP=int(log(NBR)/ln10/3)
	# print XP # = 1 or 0

Well i understand the 'order' of the math i guess, make a LOG-number from the passed NBR, and then do-something with 2.30259/3 and finaly make that an int-number.
Is that about right?
Guess the best to describe my question: i cant figure out the formula beeing used (actualy its naturaly spoken 'syntax').

	# sprintf is one topic, but what is why done with XP (1 or 0)?
	return sprintf ("%.2f%s", NBR / 10^(3*XP), U[1+XP])

Its passed NBR divided by 10 square 3 times either 0 or 1, and selecting its output string according to passed array U. (? 1+XP == XP+1 ?)
Is XP here used like 'shift' with 'getopts' (or just similar tasks)?

	# How can i check for the current line its [BP]UNT value?
	if("B" == U) { 		# This still prints output, but doesnt do the changes wanted
	## if("B" == BUNT) {	# This way it prints absolute nothing ??
		split(bitrate,B,".")
		bitrate=B[1]
	}

I've also tried if("B" in BUNT) without luck either :frowning:
This last one is an attempt to remove the .00 of the bitrate colum for the values not exceeding the Byte range.

Thank you in advance for clearing up.
Have a good day!

awk only offers log which really and correctly is ln, the "logarithmus naturalis", based on the number "e".

ln (1000) = 6,9077... . Divide this by ln (10) = 2.30259... and - voila - you'll get exactly 3, the count of zeroes in 1000 (actually the logarithm to the base 10, log10). Same holds true for e.g. 100000 or any real number.
log10 (50 ) = 1,69897
log10 (500 ) = 2,69897
log10 (5000 ) = 3,69897
log10 (50000) = 4,69897 ... see the pattern?
I use this to get the count of digits in a number.

But - we're intereseted in digit count in steps of three 1 - 1000 - 1000000 - etc., so read on

In this function the exponent to base 10 of the parameter NBR is calculated, and, as we're interested in steps of three only, divided by three, and int'ed (chopping off the .69897 or so). XP's value will be 0 for NBR up to 1000, 1 up to 1000000, 2 up to 1E9, etc. (Here lies a little problem, as for exactly 1000 etc., XP will be one too small). I admit, the name XP may be a bit misleading, as it is "exponent / 3"

^ does not mean "square", but "exponentiation". So we divide NBR by 1 if XP==0, 1000 if XP==1, 1E6 if XP==2. The 3* is to compensate for the /3 BEFORE int'ing. 5120 becomes 5.12 etc.
XP also is used as the index into the unit fields BUNT and PUNT, which, alas, start from 1 and not from 0.

No.

Both arrays are assigned in the BEGIN section from strings containing unit abbreviations. Read them "ByteUnits" and "PixelUnits". Indices are 1 .. 4. Use them like BUNT[2]. Or {for (b in BUNT) print b, BUNT}

Can be 1 (or 2..4) in BUNT only.

I have to apologize for the misleading variable nomenclature. An idiosyncrasy (from old FORTRAN days?) that I should have overcome looong ago, nowadays that spending some more chars on names will help people incl. myself understand programs.

1 Like

Bold is pretty terminal specific, and done in the presentation layer. Always design presentation on the end, after the data is parsed. Do you really want the shell to be the presentation tool? HTML is much more portable as a text formatting output, using <B>for BOLD</B> and <table>'s, <td> options for alignment.

1 Like

Valid argument, but its for a help text printed in the shell.
As in: script.sh -h
The bold text indicates (one kind of) the arguments to pass to the script.