Get "Awk" to print columns using variable?

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Post Reply
Message
Author
User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

Get "Awk" to print columns using variable?

#1 Post by sunburnt »

Or another way to print tab delimited columns?

This tries to print all the found CD/DVD device names, one per line.
More drive info is added to each line ( code not shown ).
But awk won`t use $c even though the awk manual shows variable usage.

Code: Select all

	Info=`cat /proc/sys/dev/cdrom/info`
	N=`echo "$Info" |grep 'name:' |awk '{print $3}' |grep -Eo '.$'`
	[ "$N" = '' ]&& exit
	i=0 ; c=$(($N+3))
	while [ $i -le $N ]
	do
		Drv=`echo "$Info" |grep 'name:' |awk {print $c}`'	'
		echo $Drv
		i=$(($i+1))
	done
Tab and LineFeed are both pickels, can`t identify, print, or translate easily.
\x09 and \x0a just don`t work to identify them in most cases.

### NOTE: My PC won`t do: echo $(</proc/sys/dev/cdrom/info)
It only echos or writes to a file part of the read file. But "cat" does work!

User avatar
GatorDog
Posts: 138
Joined: Tue 12 Sep 2006, 16:43

Do it with Bacon

#2 Post by GatorDog »

Fries up nicely with Bacon :wink:

Code: Select all

OPTION COLLAPSE 1
SPLIT CHOP$(EXEC$("cat /proc/sys/dev/cdrom/info | grep name:")) BY "	" TO Drv$ SIZE Drvc
FOR Index = 1 TO Drvc - 1
	PRINT Index, " ", Drv$[Index]
NEXT
The BY " " is a tab chr.
GatorDog

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#3 Post by technosaurus »

Code: Select all

#!/bin/sh
cat /proc/sys/dev/cdrom/info | while read LINE || [ "$LINE" ] ; do
	case $LINE in
		*name*)echo ${LINE##*	}
	esac
done
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

big_bass
Posts: 1740
Joined: Mon 13 Aug 2007, 12:21

#4 Post by big_bass »

*I already know you can cut out some things
and use only bash but this makes it more "readable" or keep it simple
using the (variable idea)
and dmseg will let you get a lot of info too

Code: Select all

dmesg | grep "CD/DVD" 

Code: Select all

CD_DVD_DRIVES=`dmesg | grep "CD/DVD" | cut  -f 1 -d :`
for i in  $CD_DVD_DRIVES ; do
echo $i
done
Joe

seaside
Posts: 934
Joined: Thu 12 Apr 2007, 00:19

Re: Get "Awk" to print columns using variable?

#5 Post by seaside »

sunburnt,

This line-

Code: Select all

Drv=`echo "$Info" |grep 'name:' |awk {print $c}`'	'
Looks like it should be-

Code: Select all

Drv=`echo "$Info" |grep 'name:' |awk '{print $c}'`
Regards,
s

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#6 Post by technosaurus »

Just out of curiosity, does anyone know why cat works, but file redirection doesn't.

Is there some kind of EOF character or something?
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

#7 Post by sunburnt »

Wow... Thanks guys!

technosaurus; I was puzzled with the file redirection failure, disconcerting.
Your code gives this: "drive name: sr1 sr0" The whole line...
I need sr0 ( col. 4 ) first loop and sr1 ( col. 3 ) the second, etc., etc.
The rest of the info is one more column over ( So c=$(($c+1)) to get it ).
Am using: Line=$Line`echo "$Info" |grep 've sp' |awk '{print $c}'` to build line.
I`m not sure what the " || [ "$LINE" ] " is doing, but years ago Barry showed me:
cat /proc/sys/dev/cdrom/info | while read LINE

seaside: Hey! It`s been awhile! Your code just echos the whole line also.
( See my post to technosaurus above. )
I need sr0 ( col. 4 ) first loop and sr1 ( col. 3 ) the second, etc., etc.

big_bass; Dmesg wasn`t in Puppy for a few versions, I`m surprised it`s back.
It reported my DVD-RW correctly, but as a scsi3 drive ( not important ).
But my DVD-ROM it didn`t reported as anything really. Info is hard to parse.

GatorDog; Yep, I knew BaCon would do it, but this is a Bash library.
It reports info on most system hardware. Partitions, Optical, Ram, Swap, etc.
I could make a BaCon exec. to do this function but it`d be nice to Bash it.

# As said, Bash and exec files don`t do tab well, rxvt really doesn`t like it.
This is odd and sad as Bash, sed, grep, tr, etc. are such powerful string tools.

### Found this:

Code: Select all

awk -v x=2 '{print $x}'

###> OR:

#!/bin/sh
num=$1
awk < /tmp/in -v x=$num '{print $x}' > /tmp/out
### So awk can`t use bash declared variables, variable must be set in awk command.

### It works...

Code: Select all

opticalinfo() {
	Info=`cat /proc/sys/dev/cdrom/info`
	N=`echo "$Info" |grep 'name:' |awk '{print $3}' |grep -Eo '.$'`	# number of drives
	[ "$N" = '' ]&& exit 0
	i=0 ; c=$(($N+3))
	while [ $i -le $N ]
	do
		Line=`echo "$Info" |grep 'name:' |awk -v c=$c '{print $c}'`'	'	# drive
		Line=$Line`echo "$Info" |grep 've sp' |awk -v c=$c '{print $c}'`	# speed

echo "$Line"
exit
done

seaside
Posts: 934
Joined: Thu 12 Apr 2007, 00:19

#8 Post by seaside »

Sunburnt,
I`m not sure what the " || [ "$LINE" ] " is doing, but years ago Barry showed me:
cat /proc/sys/dev/cdrom/info | while read LINE
If you are doing a "while read Line" on a file where the last line is not blank, the last entry is not returned. The "|| [ $LINE ] " picks up the last line for those cases.

Also, for Awk variables, you can grab outside variables this way-

Code: Select all

var=hello
# awk -v var="$var" 'BEGIN{print var }'
hello
It seems like you're back at some great new (and of course complicated) program again. :)

Regards,
s

big_bass
Posts: 1740
Joined: Mon 13 Aug 2007, 12:21

#9 Post by big_bass »

Hey technosaurus
Just out of curiosity, does anyone know why cat works, but file redirection doesn't.
note that I have the same question to exactly what happens
but this is what I discovered doing arrays and my take on it

if I do a file redirect I wont get array1 ,arrary2 and so forth
on a large file I just get arrary* so this leads me to believe
that it is one continuos line

but... if you use cat it is seen as numerous lines separated by the new line
character so then you do get array1, arary2 ....

Joe

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#10 Post by technosaurus »

ok here is a generic function that will be tab/space agnostic using shell only with no major bashisms (works with busybox ash)

Code: Select all

#!/bin/ash
get_column_with_string(){
COL=${1:-1};shift
STRING=${1};shift
i=1
while ([ "$i" -lt "$COL" ]) do
	CUT=${CUT}'* '
	i=$(($i+1))
done

cat $@ | while read LINE || [ "$LINE" ] ; do
	case $LINE in
		*${STRING}*)LINE=`echo $LINE`;echo ${LINE##$CUT};;
	esac
done
}

get_column_with_string 3 name /proc/sys/dev/cdrom/info
Note, this one does everything after specified column, ... just needs a minor mod to only do that column
*${STRING}*)LINE=`echo $LINE`;LINE=${LINE##$CUT};echo ${LINE%% *};;
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

#11 Post by sunburnt »

Hey technosaurus; I`ll have to stare at that a little bit to grasp it.
I`ll probably figure it out, but if I have trouble I`ll scream real loud.

big_bass; Arrays are just a string in memory that the index points to.
But how they`re handled by the various commands is a real puzzle.

seaside; I looked awhile at the Awk docs, but found it on Google.
I never noticed that "while read Line" didn`t get the last line.

### When I finish the sysinfo reporter app. I`ll post it...

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#12 Post by technosaurus »

sunburnt wrote:Hey technosaurus; I`ll have to stare at that a little bit to grasp it.
...
seaside; I looked awhile at the Awk docs, but found it on Google.
I never noticed that "while read Line" didn`t get the last line.
I use echo to squeeze out the tabs and spaces to a single space
the rest is all just substring manipulation - can replace sed,grep,cut,tr

I googled for hours one day trying to figure out a solution to the read last line problem, went through all the "big distros" forums full of the same problem with no solution, finally I just decided to think for myself and solved it on the first crack. ... I did post it in a few places, but it should be in a FAQ of some kind
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

jpeps
Posts: 3179
Joined: Sat 31 May 2008, 19:00

#13 Post by jpeps »

big_bass wrote:Hey technosaurus
Just out of curiosity, does anyone know why cat works, but file redirection doesn't.
note that I have the same question to exactly what happens
but this is what I discovered doing arrays and my take on it

if I do a file redirect I wont get array1 ,arrary2 and so forth
on a large file I just get arrary* so this leads me to believe
that it is one continuos line

but... if you use cat it is seen as numerous lines separated by the new line
character so then you do get array1, arary2 ....

Joe
You can't copy it either (with cp command). You can redirect with cat to a file, however. I think it's something to do with /proc files.

User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

#14 Post by sunburnt »

jpeps is correct I believe, redirection has only failed reading the "info" file.
But I`m guessing there`s other files in /proc that`ll do it too.
One of them, ( I can remember which one...) mostly crashes the PC when read.

technosaurus; I see the: echo ${LINE##$CUT} , I assume this cuts the tabs.
But I`m not sure what this is doing: *${STRING}*)LINE=`echo $LINE`
The "shift" commands are moving the command arguments into $1 .
But I need to study Bash / Ash more to understand what "*" and "#" are doing.

# It`s a shame "cut" doesn`t do tabs... IT SHOULD !!! It`s not as heavy as Awk.

big_bass
Posts: 1740
Joined: Mon 13 Aug 2007, 12:21

#15 Post by big_bass »

if it wasnt clear what I said here is an example
technosaurus
Quote:
Just out of curiosity, does anyone know why cat works, but file redirection doesn't.
this works correctly showing ${arr[0]} - ${arr[3]}

Code: Select all

arr=(`cat /etc/rc.d/PUPSTATE`)

echo ${arr[0]}
echo ${arr[1]}
echo ${arr[2]}
echo ${arr[3]}

this reads one long line only into ${arr[0]}
sometimes arr=$(<somefile) this is used to avoid using cat
but it has its limits and is not an exact replacement command for cat

Code: Select all

arr=$(</etc/rc.d/PUPSTATE)


echo ${arr[0]}
echo ${arr[1]}
echo ${arr[2]}
echo ${arr[3]}


seaside
Posts: 934
Joined: Thu 12 Apr 2007, 00:19

#16 Post by seaside »

big_bass wrote: this reads one long line only into ${arr[0]}
sometimes arr=$(<somefile) this is used to avoid using cat
but it has its limits and is not an exact replacement command for cat

Code: Select all

arr=$(</etc/rc.d/PUPSTATE)


echo ${arr[0]}
echo ${arr[1]}
echo ${arr[2]}
echo ${arr[3]}

big_bass,

Some extra protection and this works-

Code: Select all

 arr=(`echo "$(< /etc/rc.d/PUPSTATE)"`) 
Too many ramifications to think about... :)

Regards,
s

Post Reply