From: Seebs on 13 Apr 2010 14:50 On 2010-04-13, houghi <houghi(a)houghi.org.invalid> wrote: > It is is all that I need. Still unsure why the printf is better then the > echo as the result is the same, but I take your word for it. Using printf lets you do many things that echo can't do, and even some of the simpler ones are things which echo can't do *portably*, because of the historical clash between \c and -n. >> "Format string" is a normal string, > This is already getting difficult for me. Okay, here's the idea. "printf" is "print formatted". What it lets you do is specify, separately: 1. How you want stuff to look. 2. What stuff you want to look like that. Here's an example: $ printf "%s\n" "foo" foo $ printf "%5s\n" "foo" foo $ printf "%5d\n" 23 23 $ printf "%-5d %s\n" 23 "foo" 23 foo What this is useful for is that you can control the display of things, by modifying formats (%... is a format specifier). > And here you lost me. Sorry. I read it several times. Read it out loud. > I understand what the words mean, but somehow they do not get together > as something meaningfull. Do you have any concepts of things like "templates" or "forms"? The purpose of "printf" is to let you specify the template/form separately from the data. >> printf "The sum of %d and %d is %d.\n" "$num1" "$num2" "$((num1+num2))" >> If $num1 is 4, and $num2 is 5, the above prints >> The sum of 4 and 5 is 9. > I can copy and paste it, but I have no idea what I am doing, sorry. That > means I could do somtjing identical, but when it is a bit different, I > am lost. I guess it is because the order of things is different. > With echi I would first name $num1, then $num2 and then do whatever I > like with them. I just seem unable to get my head around first telling > what you want and then afterwards fill in the blanks. Well, you just described it exactly. That's what happens. > I know that is not everything, but that is how _I_ see it. To me that > feels impossible I have no idea yet what %d will be, let alone how many > %d I will need, so how can I determine what I should write down. You need however many you want to display. (Actually, there's some weirdness to what shell printf does with extra arguments; ignore it for now.) Look, imagine that you were gonna write: echo "The sum of $num1 and $num2 is $((num1 + num2))" Where do you need to interpolate values into the string? Where the $ signs are. So. printf "The sum of %d and %d is %d" ... Okay, what goes next? Well, what value do you want in the first spot? You want "$num1", because that's the value you were printing: printf "The sum of %d and %d is %d" $num1 ... Okay, what goes in the second spot? $num2: printf "The sum of %d and %d is %d" $num1 $num2 ... And the third spot? printf "The sum of %d and %d is %d" $num1 $num2 $((num1 + num2)) There you have it. Now, why would you do this? Imagine: for i in 1 10 100; do echo "$i bottles of beer on the wall..." done 1 bottles of beer on the wall... 10 bottles of beer on the wall... 100 bottles of beer on the wall... Oh, that's annoying, it doesn't line up. We want it to line up. With echo, you can do something elaborate to try to work around this. With printf: printf "%3d bottles of beer on the wall..." $i and you get 1 bottles of beer on the wall... 10 bottles of beer on the wall... 100 bottles of beer on the wall... It controls *formatting*. > And there lies my limitation. I have read many man pages. However I > seldom understand what they mean. I understand the words, but very > seldom the meaning. That's come across some. Do you usually have trouble abstracting things from examples to general patterns? > > I read the 4 manpages and the info page and I have now even less > understanding. Again, it is _my_ limitations. I do understand that it is > very simple for most people. I just seem unable to get my head around > it. e.g. it says: > Thus, > printf("%'.2f", 1234567.89); > results in "1234567.89" in the POSIX locale, [...] > > And I get: > houghi(a)penne : printf ("%'.2f", 1234567.89); > bash: syntax error near unexpected token `"%'.2f",' That's because you're reading the man page for a DIFFERENT thing called "printf". You're looking at the man page for the C function. You should be able to spot that, because in shell, you don't use () like that. I'm not sure how to explain why this ought to be obvious, but in general, I would expect that, when you had five or ten examples none of which used () or ended lines with ;, and you saw a new example which used () and ended a line with ;, I guess that would be something I'd expect to make you think "hey, this looks different". > I also know that many people do not understand or even do not believe me > that I can't grasp so many things. I will try to remember if I post > something here to replace the echo command with the printf, so not to > offend anybody. That won't work until you figure out how printf works. I guess the second question is... What are your goals? Is this purely a hobby? Are you aiming for a job doing this stuff? How much it matters whether you understand what you're doing depends somewhat on why you're doing it. -s -- Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam(a)seebs.net http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
From: Seebs on 13 Apr 2010 14:53 On 2010-04-13, thdyoung(a)googlemail.com <thdyoung(a)googlemail.com> wrote: > i don't want to interfere but folk shy away from man pages coz they're > so darned bad to read No, they really aren't. > face it - a miraculous habit has been widely established on the net > via groups and BBs of helping each other: Yes, and doing it as inefficiently as possible. > rolling it back w sharp > reproofs about reading the man pages is kind of counter-counter > cultural. Maybe, but it's also *right*. We have finite time. Spend it wisely, and don't spend other people's time cheaply just because it's not your time. > all us lurkers glean vast amounts of learning from these groups - of > course, we do: we are here to learn coz it is far better than the man > pages It's not better, it's *different*. It's aimed at solving a different kind of problem. Failing to read the man pages first is insulting and rude; it's a statement to everyone else that ten seconds of the time of every single other reader in the newsgroup, and a minute or more from a few of them, is worth much less than five minutes of your time. I read and participate in these groups because I want to help people who have shown a willingness to put in time and effort to learn, and want a hand with it. I'm not here to help people who are too busy to put any of their own time into learning. And with that, *plonk*. -s -- Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam(a)seebs.net http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
From: Janis Papanagnou on 13 Apr 2010 15:20 houghi schrieb: > pk wrote: [...] > >> The general format of printf is >> >> printf <format string> <arguments> > > OK. > >> "Format string" is a normal string, > > This is already getting difficult for me. The format string will define the output format; it will be interpreted and expressions like %s or %d are like variables or placeholders for subsequent arguments; %s will be replaced by a string, %d will be replaced by a number. printf "+++ %s +++ %d +++\n" "Hello" "5" will result in +++ Hello +++ 5 +++ Instead of "Hello" and "5" you can expand variables which contain strings or numbers. You can have an arbitrary amount of such % placeholders, just make sure you have one argument for each placeholder following the format string. > >> but it contains some special sequences >> that are special to printf, called "format specifications". > > Grasping on here. > >> "%s" above is >> one of those. When printf sees one of those sequences, it replaces it with >> the next argument in its list, and formats it accordingly. It follows that >> (usually) if the format string contains n format specifications, you have to >> supply n arguments to printf after the format string. For example, the >> format specification %d is to print integers, so you do this: > > And here you lost me. Sorry. I read it several times. Read it out loud. > I understand what the words mean, but somehow they do not get together > as something meaningfull. Is the above example probably more clear than pk's textual explanation? > >> printf "The sum of %d and %d is %d.\n" "$num1" "$num2" "$((num1+num2))" >> >> If $num1 is 4, and $num2 is 5, the above prints >> >> The sum of 4 and 5 is 9. > > I can copy and paste it, but I have no idea what I am doing, sorry. That > means I could do somtjing identical, but when it is a bit different, I > am lost. I guess it is because the order of things is different. In the format string you have three placeholders %d for decimal numbers. The arguments that follow will be substituted, one argument for one placeholder, from left to right. "$num1" will be evaluated and fills the first %d, "$num2" fills the second %d, and "$(( $num1 + $num2 ))" is an arithmetic expression that will be evaluated by the shell, and then it fills the third %d. > > [...] To me that > feels impossible I have no idea yet what %d will be, let alone how many > %d I will need, so how can I determine what I should write down. %d is a placeholder for a decimal number argument that folows. You need one % placeholder for each argument. (Simplified speaking.) > >> The format specifications are many, %s and %d are just two of them. >> Simplifying, %s is for strings, %d for integers, %f and %g for floating >> point numbers, %c for characters, %% for a literal %. There are many others, >> and also each specification can have optional modifiers that change the >> formatting. For example, %5d is like %d, but uses five characters to print >> the integer, even if it's shorter (pads with spaces); likewise, %05d pads >> with zeros. > > Sorry. Way over my head. Besides %s and %d there are placeholders for other data types and their formatted output. You don't need that in the beginning. Here's one more set of examples, please try them out (the +++ is just for you to see where the %05d, %5d, and %d, begins and ends) printf "+++%05d+++\n" 5 printf "+++%5d+++\n" 5 printf "+++%d+++\n" 5 > >> Printf has another advantage over echo: it recognizes many special escape >> sequences that echo does not recognize (or recognizes only with -e in >> certain implementations), like \n or \t. > > I understand that. That is why I avoid getting in such situations. Sometimes you cannot avoid that situation. (If your echoed variables have been filled by arbitrary user input or output from another process that you read into the variable and that contains those characters.) Believe it. > >> [...] > > And there lies my limitation. I have read many man pages. However I > seldom understand what they mean. I understand the words, but very > seldom the meaning. even with `man date` I need to look at some part of > the code I have already done previously to look what I need to do and > even then try out all the options to see what is going on. Then google for "<whatever> examples". You can certainly find a lot. I am positive that examples from books and from the Web will help you; before you start to experiment how randomly collected shell code works. > >> In case you >> shell's man page for printf if scant, I suggest you do "man 3 printf" to see >> the C printf man page with the full specs, to which the shell's printf is >> mostly compliant (with the obvious differences/limitations). > > I read the 4 manpages and the info page and I have now even less > understanding. It was prabably an advice that you cannot use on your comprehension level. > Again, it is _my_ limitations. I do understand that it is > very simple for most people. I just seem unable to get my head around > it. e.g. it says: > Thus, > printf("%'.2f", 1234567.89); This is syntax for the "Programming Language C". While printf "%'.2f" 1234567.89 is syntax for the shell programming languages. > results in "1234567.89" in the POSIX locale, [...] (ignore that part about POSIX locales for now) > > [...] > > I also know that many people do not understand or even do not believe me > that I can't grasp so many things. I will try to remember if I post > something here to replace the echo command with the printf, so not to > offend anybody. I, meanwhile, believe you and understand that you have problems with the shell (or programming, or [English] language) concepts. Just curious; why do you try to do shell programming at all? There are certainly many much better suited programming languages with less pitfalls and inconsistencies than you'll meet in the shell language. Janis > > houghi
From: Seebs on 13 Apr 2010 17:24 On 2010-04-13, houghi <houghi(a)houghi.org.invalid> wrote: > Seebs wrote: >> Using printf lets you do many things that echo can't do, and even some >> of the simpler ones are things which echo can't do *portably*, because >> of the historical clash between \c and -n. > Again I believe what you say, although I have no idea what it means. Let me see if I can simplify it. On different systems, the "echo" command does different things. Because of this, there are some things that it is very hard to write so they will behave the same way on different computers. For instance, my laptop and my desktop do not have the same behavior for "echo". >> Okay, here's the idea. >> "printf" is "print formatted". What it lets you do is specify, separately: >> 1. How you want stuff to look. > dasicaly just the output of $foo Slow down. I'm not talking about just this one circumstance. I'm explaining what printf does *IN GENERAL*. The point of printf is that you can change how something is displayed. >> $ printf "%-5d %s\n" 23 "foo" >> 23 foo > Whoosh!. Sorry. Okay, let's walk through it. "%-5d %s\n" We see the first '%'. That means that we're going to find instructions for how to display something. We start reading... % <-- we're going to format something - <-- it will be left-justified ("foo " instead of " foo") 5 <-- it will be printed 5 characters wide d <-- ah-hah! We are printing a number We now have instructions: "Print, left-justified, taking 5 spaces, as a number..." So we take the next argument (the first argument after the format string), which is "23". We convert it to a number, and print it out, and get "23 ". Now we find a space. It's not a %, so we just print it, so we have "23 ". Now we find another %. Let's walk through this... % <-- we are going to format something s <-- it will be a string Okay, we'll print the next argument as a string. The next argument is "foo". So we print it, and we're now to "23 foo". Then we see a \ and an n, and that's a newline, so we print "23 foo" and then a newline. >> What this is useful for is that you can control the display of >> things, by modifying formats (%... is a format specifier). > Very seldom do I need to format the output. I just need to do an `echo > $foo` variation. But sometimes you run into things like, say, wanting to print things without starting a new line. There are at least two ways to do that with echo, maybe three, but you can't be sure that what works on one machine will work on another, so none of them are *reliable*. >> Do you have any concepts of things like "templates" or "forms"? The >> purpose of "printf" is to let you specify the template/form separately >> from the data. > No, sorry. I never needed to specify anything. You've never in your life encountered a form which had data in it? Done any kind of combination of data with output? Do you know how to start a letter? Dear Houghi, What's happening there? We have a template: Dear <name>, and then we want to insert a value (the recipient's name) into the spot where <name> is. >> You need however many you want to display. (Actually, there's some weirdness >> to what shell printf does with extra arguments; ignore it for now.) > I almost never know that up front. I can't comprehend this. You want to display output. By the fact that you have some idea what you want to display, you *ABSOLUTELY MUST* know what you want to display. You can't write an "echo" command without knowing what you want to display either. >> Look, imagine that you were gonna write: >> >> echo "The sum of $num1 and $num2 is $((num1 + num2))" >> >> Where do you need to interpolate values into the string? Where the $ >> signs are. > > I would most likely do something like: > #!/bin/bash > NUM1=1 > NUM2=2 > let "TOTAL = $NUM1 + $NUM2" > echo "The sum of $NUM1 and $NUM2 is $TOTAL" > > That way the first three (ok 4) lines do what I want and the last one > will show the result. It also shows my tought processs. I have one. I > the realize I have something else as well. Then I want to add those two > up. And then I thing" why not show the result? Riiiight. And since around the time we figured out that you could use fire to cook things, what people have done is called "planning". You look at that, you think 'okay, here's what I want, now how do I do it'. So you take the above, and instead of writing the names, you write a description of what they are: "The sum of <number> and <number> is <number>" And then you add the numbers in order: "The sum of <number> and <number> is <number>" $NUM1 $NUM2 $TOTAL and then, because it's printf, you spell "<number>" as "%d": "The sum of %d and %d is %d" $NUM1 $NUM2 $TOTAL > I rarely need formatting. I understand that in those cases printf will > be better, but not why printf should replace echo if I am not interested > in formatting. Because whether or not to print a newline is formatting, and because some versions of echo can't print some strings. >> That's come across some. Do you usually have trouble abstracting things >> from examples to general patterns? > Yes. What I need is almost exactly what I am looking for and then do > minor changes. Then I do not think you should spend much time trying to program. Programming is ALL abstraction. > It is purely a hobby. If I screw up, I will be normally the only one who > is affected. Things I have done for myself are a wallpaper changer (The > existing ones do not work for me, due to several reasons) wallpaper > makers, screen capture script, signature maker and stuff like that. > So basically automating things I am too lazy to do myself all the time > and where I can not find a program that does what I want it to do. That can make sense. I think, though, that the most useful thing you could do is try to study how abstraction works, so you can learn to generalize. That skill will be amazingly useful to you in every possible aspect of your life. Learn to do that, and you will be happier and more successful, and you'll find programming a lot easier. -s -- Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam(a)seebs.net http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
From: Jon LaBadie on 13 Apr 2010 18:03
Regarding echo vs. printf, pk wrote: > > Printf has another advantage over echo: it recognizes many special escape > sequences that echo does not recognize (or recognizes only with -e in > certain implementations), like \n or \t. > Houghi, pk and I represent different sides of the problem. I've worked most of my UNIX life in environments where echo DID recognize \n, \t, etc. So I expect other behaviors, such as pk considers normal, as abberant. I'd re-write pk's statement to say that as printf is consistant in recognizing the escape sequences like \n, \t, etc. while echo is not. If you are going to do simple literal text that does not contain escape sequences, go ahead and use echo. For example: echo "Hello World!" But is that easier than: printf "Hello World!\n" Well I guess it is harder because you have to add the '\n' in printf. But that is balanced by times you don't want a newline. For example suppose you want to ask for some data to be keyed in by the operator. Further, suppose you want the data entry on the same line as the prompt. With printf you might do this: printf "Enter your last name: " read LastName But with echo you would have to remember, does my echo suppress the default newline by putting a '\c' at the end or by using a '-n' option? I.e. should it be echo "Enter your last name: \c" OR echo -n "Enter your last name: " And what about when I copy my script to my laptop, or my next new computer. Will its echo work the same way as this version? I realize you are not "smart enough" to learn the intricacies of printf :) but I find the ability to format multiple lines of simple text a great feature. For example, suppose you are printing a list of names, first and last. You could use a printf like this: printf "%s %s\n" "$FirstName" "$LastName" with output like (which is no different than you could get with echo): George Washington John Adams Thomas Jefferson But changing each %s to %12s would change the output to: George Washington John Adams Thomas Jefferson Ahh, maybe you wanted left instead of right alignment, make it %-12s: George Washington John Adams Thomas Jefferson Or the first one %12s and the second one %-12s George Washington John Adams Thomas Jefferson Lots and lots of flexibility that would be difficult to do with echo. Yet the simple things are still simple (and more portable) with printf. Jon |