ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I am trying to read the last 5 lines of a log in reverse order. The code below writes the last 5 to a temporary file in reverse order. But the read gets the first word (space delimited?), and not the first line.
How can I get the entire line?
Code:
tail -n5 /../wrapper.log | tac > tempfile;
while read wLine
do
printf $wLine;
done < tempfile;
Well.. two problems here. First, the syntax of the printf command is not correct: it should be
Code:
printf FORMAT [ARGUMENT]...
Second, you have to use double quotes to prevent word splitting and make printf see the value of the wLine variable as a single string, despite the presence of spaces or TAB characters:
Code:
while read wLine
do
printf "%s\n" "$wLine"
done < tempfile
where the printf statement with this specific format (a string followed by newline) is equivalent to echo.
Well.. two problems here. First, the syntax of the printf command is not correct: it should be
Code:
printf FORMAT [ARGUMENT]...
Second, you have to use double quotes to prevent word splitting and make printf see the value of the wLine variable as a single string, despite the presence of spaces or TAB characters:
Code:
while read wLine
do
printf "%s\n" "$wLine"
done < tempfile
where the printf statement with this specific format (a string followed by newline) is equivalent to echo.
I do agree with that said.
But if you omit the Format string the first argument is used a format string, which will be expanded to it self, if it does not contain any format specification.
Code:
a="hello a string with spaces"
printf $a
printf '\n'
printf "$a\n"
Of course this is not proper programming, as this construct is misleading.
Allbeit that the desired result is printed.
But if you omit the Format string the first argument is used a format string, which will be expanded to it self, if it does not contain any format specification.
Code:
a="hello a string with spaces"
printf $a
printf '\n'
printf "$a\n"
Of course this is not proper programming, as this construct is misleading.
Allbeit that the desired result is printed.
Actually, the usage of printf is indeed (as posted by colucix)
Code:
printf FORMAT [ARGUMENT]...
This is actually very similar to usage of printf() function in C.
Your
Code:
printf "$a\n"
is correct and there's nothing wrong with that, since the FORMAT string can contain string literals, just as in C you would write
Code:
printf("Hello World\n");
instead of
Code:
printf("%s %s\n", "Hello", "World");
Following, however,
Code:
a="hello a string with spaces"
printf $a
will not print the desired output, because
printf $a
will be substituted by
printf hello a string with spaces
and 6 arguments will be passed to printf. printf will interpret the first argument as a format string, and because it does not contain any references (such as %s or %f), printf will have no reason to use any of the other arguments. Therefore, only "hello" will be printed, the rest of the arguments will be discarded (unlike echo which will print the entire string). In your example, the double quotes are required around $a:
There is one difference between Bash printf and C printf() function, though:
Code:
printf '<%s>\n' 'First' 'Second' 'Third'
will output
Code:
<First>
<Second>
<Third>
because printf command will apply the FORMAT to the parameters, outputting the result, until there is no more output to print. Except, of course, if FORMAT does not consume any parameters.
Here is the relevant note from the Bash manual (bash-builtins man page), edited for clarity:
Quote:
Code:
printf [ -v VAR ] FORMAT [ ARGUMENTS... ]
Write the formatted ARGUMENTS to the standard output under the control of the FORMAT. The FORMAT is a character string which contains three types of objects: plain characters, which are simply copied to standard output, character escape sequences, which are converted and copied to the standard output, and format specifications, each of which causes printing of the next successive argument. In addition to the standard printf(1) formats, ‘%b’ causes printf to expand backslash escape sequences in the corresponding argument, (except that ‘\c’ terminates output, backslashes in ‘\'’, ‘\"’, and ‘\?’ are not removed, and octal escapes beginning with ‘\0’ may contain up to four digits), and ‘%q’ causes printf to output the corresponding argument in a format that can be reused as shell input.
The -v option causes the output to be assigned to the variable VAR rather than being printed to the standard output.
The FORMAT is reused as necessary to consume all of the ARGUMENTS. If the FORMAT requires more ARGUMENTS than are supplied, the extra format specifications behave as if a zero value or null string, as appropriate, had been supplied. The return value is zero on success, non-zero on failure.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.