LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-09-2006, 11:12 AM   #1
tizedboy
LQ Newbie
 
Registered: Oct 2006
Location: Germany
Distribution: Suse 10.1
Posts: 13

Rep: Reputation: 0
Just starting scripting - help!


Hi all,

I am just starting scripting and I have a question. I wonder if there is a shorter way of doing this.

I want to format the output from "id" command which looks like this:
uid=500(Administrator) gid=513(None) groups=0(root),513(None),544(Administrators),545(Users),1004(Debugger Users)

Now I want to fotmat it so that every of the 3 elements will be on its own line, ie.

I tried this:
id | tr -s " " "\n" (after every space put end-of-line character)

The result was that, (Debbuger Users) was cut into two pieces and this is exactly what I wanted to avoid.

Thanks!
 
Old 10-09-2006, 11:51 AM   #2
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Hi,

First that comes to mind:

id | sed 's/) /)\n/g'

Substitute ) and a space with ) and a new-line.

Hope this helps.
 
Old 10-09-2006, 01:53 PM   #3
tizedboy
LQ Newbie
 
Registered: Oct 2006
Location: Germany
Distribution: Suse 10.1
Posts: 13

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by druuna
Hi,

First that comes to mind:

id | sed 's/) /)\n/g'

Substitute ) and a space with ) and a new-line.

Hope this helps.
Hi,

thanks for your prompt reply. Please observe that there are three elements and the main component is the "=" sign. With this I mean
1)uid=500(Administrator)
2)gid=513(None)
3)groups=0(root),513(None),544(Administrators),545(Users),1004(Debugger Users)

Which means group=........(Debugger Users)also has to be one thing on one line.

What I tried was along way which I guess isn't a good solution especially when you have many outut lines from <id> command

So I went like this:
id | cut -d " " -f1 > file1 (cut first field and write to file1)

id | cut -d " " -f2 > file2(cut second field and write to file2)

cat file2 >> file(append file2 to file1)

then

id | cut -c 38-200(get the last field from character 38 to the end the write to file3)

cat file3 >> file 1(append file3 to file 1)

I hope there is a shorter way .

Regards
 
Old 10-09-2006, 01:59 PM   #4
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Hi,

That's exactly what my command does:

Code:
 $ fakeid="uid=500(Administrator) gid=513(None) groups=0(root),513(None),544(Administrators),545(Users),1004(Debugger Users)"

$ echo $fakeid | sed 's/) /)\n/g'
uid=500(Administrator)
gid=513(None)
groups=0(root),513(None),544(Administrators),545(Users),1004(Debugger Users)

 $ id | sed 's/) /)\n/g'
uid=500(druuna)
gid=500(internet)
groups=500(internet),400(users),501(visitor)
I cannot think of a way to do this any shorter, but maybe it could be done.

Hope this helps.
 
Old 10-09-2006, 02:12 PM   #5
tizedboy
LQ Newbie
 
Registered: Oct 2006
Location: Germany
Distribution: Suse 10.1
Posts: 13

Original Poster
Rep: Reputation: 0
Yeah!

I could see now it is working. I didn't type correctly sed 's/) /)\n/g', that's why I got wrong results. The solution ie perfect because it ignores the space (Debugger User) and only takes care of ) .

Thanks a lot.
I am starting to like this :-)
 
Old 10-10-2006, 08:55 AM   #6
tizedboy
LQ Newbie
 
Registered: Oct 2006
Location: Germany
Distribution: Suse 10.1
Posts: 13

Original Poster
Rep: Reputation: 0
Hi again,

My question today is:

How to quickly detemine what command(s) to use. I mean for me commands like tr, grep and sed 's///g' do almost the same thing.

Thanks.
 
Old 10-10-2006, 09:21 AM   #7
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Hi,

That comes with experience. Even now, after years and years of 'playing' with computers (I started in 1981 with a apple II Europlus), I still discover commands I haven't used/heard of before (seq is the last one I 'discovered').

Linux and unix have multiple ways of doing the same thing. Sometimes the chosen solution isn't to elegant or resource friendly but sometimes that isn't important (the work needs to be done).

And always try to 'see' other solutions that could make your work easier. For example: You initially focused on a space to solve the problem, I initially chose the equal sign. After looking at the string a bit longer I noticed the )<space> that could be used in an elegant way. Always take a little time to analyze the problem and work towards that what you know.

Another tip: Look at and try to understand (bash) scripts you come across, most of my knowledge comes from looking at and playing with scripts that where written by others.

Hope this helps.
 
Old 10-10-2006, 09:40 AM   #8
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Quote:
Originally Posted by tizedboy
Hi again,

My question today is:

How to quickly detemine what command(s) to use. I mean for me commands like tr, grep and sed 's///g' do almost the same thing.

Thanks.
My solution to this question has evolved into one answer: 'perl'. Many will argue that it is overkill for most problems, which is true. However, I never bump into the problem of not quite getting there with one tool or the other. Perl can be used for one-liner command-line solutions, as well as for full-blown applications, and all of the spectrum in between. Concepts that are central to the behavior of perl are mostly borrowed from other tools, and once you understand those concepts, you will find it easy to understand examples that are cited using the usual assortment of tools that you mentioned.

My $.02 worth.

--- rod.

EDIT:
BTW, the perl solution to this problem:
Code:
id | perl -e 'while(<>){ s/\) /\)\n/g; print $_;}'

Last edited by theNbomr; 10-10-2006 at 09:44 AM.
 
Old 10-10-2006, 10:00 AM   #9
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
...the Bash equivalent of Druuna's sed line:
Code:
fakeid="uid=500(Administrator) gid=513(None) groups=0(root),513(None),544(Administrators),545(Users),1004(Debugger Users)"

echo -e ${fakeid//) /\)\\n}
 
Old 10-10-2006, 10:30 AM   #10
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by tizedboy
Hi again,

My question today is:

How to quickly detemine what command(s) to use. I mean for me commands like tr, grep and sed 's///g' do almost the same thing.

Thanks.
Imagine this (Python):
Code:
>>> import os
>>> os.getlogin()
'root'
>>> os.getgid() #get real group id of current process
0
>>> os.getuid()
0
>>> os.getgroups() #return list of supplementary groups.
[0, 1, 2, 3, 4, 6, 10]
Also, no need to use regular expressions that much..
Code:
>>> fakeid="uid=500(Administrator) gid=513(None) groups=0(root),513(None),544(Administrators),545(Users),1004(Debugger Users)"
>>> for items in fakeid.split(" ",2): #stop at 2 space splits...
...     print items
...
uid=500(Administrator)
gid=513(None)
groups=0(root),513(None),544(Administrators),545(Users),1004(Debugger Users)
 
Old 10-11-2006, 06:19 AM   #11
tizedboy
LQ Newbie
 
Registered: Oct 2006
Location: Germany
Distribution: Suse 10.1
Posts: 13

Original Poster
Rep: Reputation: 0
Thanks guys for your contribution!

Today I wanted to find the bigest file/directory . As a small exaple I used the current directory . So I went like this:
ls -l | sort -n -r -k 5 | head -n 1
(list me the files, sort them numerically with reference to the fifth column, reverse the sort to make it in discending order , after that cut the first line and that is what I wanted)

Again any suggestions on shorter ways? It seems I like to go too much around :-)

Thanks.
 
Old 10-11-2006, 06:50 AM   #12
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by tizedboy
Thanks guys for your contribution!

Today I wanted to find the bigest file/directory . As a small exaple I used the current directory . So I went like this:
ls -l | sort -n -r -k 5 | head -n 1
(list me the files, sort them numerically with reference to the fifth column, reverse the sort to make it in discending order , after that cut the first line and that is what I wanted)

Again any suggestions on shorter ways? It seems I like to go too much around :-)

Thanks.
ls -1S | head -n 1
 
Old 10-16-2006, 06:47 AM   #13
tizedboy
LQ Newbie
 
Registered: Oct 2006
Location: Germany
Distribution: Suse 10.1
Posts: 13

Original Poster
Rep: Reputation: 0
Hi,

I have a new problem. I have a simple game script. A user has to guess a randomly generated number, if he enters the same number as the one generated by the program, then the game is over. If he enters smaller number or bigger, he gets appropriate message.

My problem is: Users have to input only numbers, if they input anything other than a number, they should be informed of this. Now how should I check this?
Should I use:
if $input isnum? or test or maybe grep -v [0-9]?; but how?

---------------------------------------------------------------
Here is the script
------------------------------------------------
# A simple guessing script
# !/bin/bash
clear
times=0
randomnumber=$[$RANDOM * 40 / 32767]
try=0

echo "You have 10 tries "
echo
while [ $times -ne $randomnumber ]
do
echo -n "Please enter a number between 1 and 40 : "
read input
# here is where I wanted to enter the condition
#if [ isnum $input ]
#then
#echo "You can use only numbers "
try=$[$try+1]
if [ $try = 11 ]
then
echo " You have used all tries "
exit
else
if [ $input -eq $randomnumber ]
then
echo "Excellent "
exit
else
if [ $input -lt $randomnumber ]
then
echo "Too small "
else
echo "Too big "
fi
fi
fi
done

---------------------------------
 
Old 10-16-2006, 08:57 AM   #14
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Hi,

Here are 2 ways to solve this problem.

1) Use grep and the exit status to determine if it's a number:
Code:
#!/bin/bash

echo -n "Give number (1-40) : "
read input

echo $input | grep "[0-9][0-9]*" > /dev/null 2>&1
if [ "$?" -ne 0 ]
then
  echo "Use a number please"
fi
If a command exits succesfull, the exit code will be 0 (zero). If it is not succesfull it will be something other then 0. The $? variable is special, it holds the exit code from the very last command executed.
So after the echo $input | grep....... the exit code is checked and if it is not 0 (zero) something other then a number is given.

2) Use bash internals, no need for external (i.e. grep in the previous example) command(s):
Code:
#!/bin/bash

typeset -i input

echo -n "Give number (1-40) : "
read input

if [[ $input == "0" ]]
then
  echo "Use a number please"
fi
You (mis-)use bash' typeset -i input to declare input to be an integer. If anything else then a number is given, $input will be 0 (zero).
Downside: You cannot use 0 (zero). I.e: Give number (0-40). This is also the reason why I wrote (mis-)use

Personally I would choose solution number 2. I try to use bash internals as they are faster and there is no need for external commands.

Hope this helps.
 
Old 10-16-2006, 11:04 AM   #15
Tischbein
Member
 
Registered: Oct 2006
Distribution: debian
Posts: 124

Rep: Reputation: 15
Hmm, number from 1-40... "R2-D2" would pass your test! Try "^[1-9][0-9]*$" instead.

(Note: The ^ and $ are special chaaracters indicating the beginning and end of the line, so this guarantees that there is nothing but a number on the line. The [1-9] guarantees no leading zeros or minus signs. Then you can safely use numerical tests such as [ $input -le 40 ])

Bon voyage, Hockerbein


Oh, on the question of "how do you find the right command top do such-and-such" question, there are several search mechanisms:

A:- One is the command line "apropos keyword". (If that gives you nothing, as it just did on my brand new install, run the makewhatis indexing command first, /usr/sbin/makewhatis).

B:- Another is to browse man pages, specifically man something similar and go straight to the "SEE ALSO" section at the bottom of the man page.

On the scripting issue, I agree that perl has it all, however I'd consider there to be a heirarchy of languages for increasingly complicated code:

tr < sed < awk < perl

I dislike bash but it's useful I suppose. I write most of my scripts in either sed or awk. I sometimes use perl instead of sed on systems with a cruddy sed. E.g.:

sed 's?\(stuff\)ing?\1\1 <--- newline has to be typed literally on older systems
?g'

is equivalent to:
perl -p -e 's?(stuff)ing?$1$1\n?g' <-- newline is just \n

There are also new object oriented scripting languages such as Ruby and Python that have a great fan following, but I'm not convinced that they're anything to get excited about. But if you're keen, put them on your list of tricks to try out sometime.

Last edited by Tischbein; 10-20-2006 at 03:57 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
teaching shell scripting: cool scripting examples? fax8 Linux - General 1 04-20-2006 04:29 AM
starting xprogram without starting X server. bruse Linux - Newbie 9 04-26-2005 07:05 PM
Auto starting and/or scripting Infernal211283 Linux - Newbie 1 03-22-2005 12:41 PM
Won't Boot - Starting Printer Service - Starting CUPS jeansond Linux - Newbie 0 10-11-2004 06:39 PM
Starting apps after starting xfce?? gtgoku Slackware 2 08-21-2004 01:49 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:34 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration