Explanation needed on how I can repeat a character in POSIX shell
The following answer on Stack Overflow,
How can I repeat a character in bash?
imposes one plausible way of POSIX-ly repeating a single character, as follows. In this example let's use the equal sign 100 times:
printf %100s | tr " " "="
My problem is that I don't understand how it works, and I would prefer a straightforward explanation. Please refrain from comments like read the manual, I did so, and since I am not clever from it, I am asking this question as I've never used tr
, nor seen such a printf
statement.
shell posix printf tr
add a comment |
The following answer on Stack Overflow,
How can I repeat a character in bash?
imposes one plausible way of POSIX-ly repeating a single character, as follows. In this example let's use the equal sign 100 times:
printf %100s | tr " " "="
My problem is that I don't understand how it works, and I would prefer a straightforward explanation. Please refrain from comments like read the manual, I did so, and since I am not clever from it, I am asking this question as I've never used tr
, nor seen such a printf
statement.
shell posix printf tr
add a comment |
The following answer on Stack Overflow,
How can I repeat a character in bash?
imposes one plausible way of POSIX-ly repeating a single character, as follows. In this example let's use the equal sign 100 times:
printf %100s | tr " " "="
My problem is that I don't understand how it works, and I would prefer a straightforward explanation. Please refrain from comments like read the manual, I did so, and since I am not clever from it, I am asking this question as I've never used tr
, nor seen such a printf
statement.
shell posix printf tr
The following answer on Stack Overflow,
How can I repeat a character in bash?
imposes one plausible way of POSIX-ly repeating a single character, as follows. In this example let's use the equal sign 100 times:
printf %100s | tr " " "="
My problem is that I don't understand how it works, and I would prefer a straightforward explanation. Please refrain from comments like read the manual, I did so, and since I am not clever from it, I am asking this question as I've never used tr
, nor seen such a printf
statement.
shell posix printf tr
shell posix printf tr
edited yesterday
Peter Mortensen
88158
88158
asked yesterday
Vlastimil
7,8171261134
7,8171261134
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
In short, printf %100s
will print 100 spaces, and tr " " "="
will convert those spaces to equal signs, effectively printing 100 equal signs.
Breaking it down:
printf
is a shell built-in. It typically takes two or more arguments, the first of which is a "format string" and the rest will be used to fill up placeholders in that format string. Once that template is fully filled, it will print out the result. If there are more arguments left, it will start over, filling up more arguments and printing the resulting string.
The format string used for printf
takes format specifications, which start with %
and end with a single letter, so %d
means an integer (using the decimal base, therefore "d"), %f
means a floating-point number and %s
means a string of characters. Characters other than letters after the %
are modifiers for the format specification and, in particular, numbers are used to specify the requested length of the field on output. So %100s
will format the string to have at least 100 characters, it will pad it with spaces and it will keep it aligned right (in other words, add spaces at the beginning of the string.)
If passed an extra argument, it would use it for that %s
field, so for example printf %100s abc
will print 97 spaces (to get to 100 total, considering the 3 in "abc") followed by the actual string "abc". But if no argument is given, then the format specification is filled with an empty or null argument (which is an empty string for %s
, it would be 0 for %d
, etc.) So that's the same as if an empty string was passed, such as printf %100s ''
. The end result is that only the 100 character padding is printed.
So, putting it all together, printf %100s
results in 100 spaces printed.
Now tr
is a tool to translate characters from input to output. It takes two arguments, SET1 and SET2, each a set of characters, and then translates the first character of SET1 into the first of SET2, the second character of SET1 into the second of SET2 and so on. tr
reads its input from stdin and writes it back to stdout (so it's very useful in pipelines like the one above.) tr
will always translate all occurrences of that character in a given string.
For example, tr aeiou 12345
will translate lowercase vowels into the numbers 1 to 5 in that order, so it will translate "queueing" into "q52523ng" for example. You can also pass it character ranges, such as tr a-z A-Z
to turn any lowercase letter into its corresponding uppercase one.
So tr " " "="
is simply translating spaces into equal signs throughout the string. The first space needs to be quoted to be recognized as an argument. The =
doesn't actually need to be quoted, but doing so doesn't hurt. tr " " =
would have worked the same.
Putting it all together, print 100 spaces, then translate each of them into equal signs.
Hopefully this explains it in enough detail, but if there's still something you don't understand, please leave a comment and I'll try to address that.
Just checking, would the following be more syntactically correct?:printf '%100s' ' ' | tr " " "="
– Vlastimil
yesterday
2
@Vlastimil Actuallyprintf '%100s' ''
, with an empty string... I updated the answer to include that. In this particular case, empty string or a single space wouldn't make a difference, but you can see a difference inprintf '%sxn'
, which is the same asprintf '%sxn' ''
but different fromprintf '%sxn' ' '
. I hope that helps!
– filbranden
yesterday
1
+1 for mention thattr
operates on sets of characters. This is often left out.
– Sergiy Kolodyazhnyy
yesterday
add a comment |
The printf
command uses its first argument as a format for printing its subsequent arguments. printf %100s
prints out its arguments padded to 100 characters wide, using spaces (on the left). There is no argument provided to format, so it formats the empty string once, and outputs 100 spaces. You can see that:
$ printf %100s | hexdump -C
00000000 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |
*
00000064
(20 is the hex for a space; *
means the previous line repeated)
The format strings use approximately the C Xprintf
specifiers: %
, an optional width to fit the formatted value into, and a type of format to use. s
is string formatting, and strings are padded with spaces on the left by default. There could be multiple formats, or other literal parts: printf "a%10sbn" hello
prints
a xb.
tr
replaces selected characters in its standard input with selected replacements, and prints the result to its standard output. tr " " "="
has a single character to be replaced - a space - and a single character to replace it with - an equals sign. It thus turns every space in its input into an =
, and leaves the rest unchanged. You can try that as well:
$ tr " " "="
hello world
hello=world
(I typed the "hello world")
You could have multiple replacements: tr abc def
turns a into d, b into e, c into f, and leaves the rest unchanged. Here it's just a single character, since that was what printf
could cheaply generate.
The pipe |
causes the output of the command on the left, printf %100s
, to be used as the input to the command on the right, tr " " "="
. That is, a hundred consecutive spaces are given to tr
, and each one of them is replaced with an =
, with the new string printed out.
printf %100s | tr " " "="
====================================================================================================
Just checking, would the following be more syntactically correct?:printf '%100s' ' ' | tr " " "="
– Vlastimil
yesterday
1
Formatting a space and padding it with spaces is going to give the same output as formatting an empty string and padding with spaces, but it's not structurally equivalent. Perhaps it's more "correct" in terms of clarity about what's going on, but not syntactically, and they are different commands.
– Michael Homer
yesterday
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f492630%2fexplanation-needed-on-how-i-can-repeat-a-character-in-posix-shell%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
In short, printf %100s
will print 100 spaces, and tr " " "="
will convert those spaces to equal signs, effectively printing 100 equal signs.
Breaking it down:
printf
is a shell built-in. It typically takes two or more arguments, the first of which is a "format string" and the rest will be used to fill up placeholders in that format string. Once that template is fully filled, it will print out the result. If there are more arguments left, it will start over, filling up more arguments and printing the resulting string.
The format string used for printf
takes format specifications, which start with %
and end with a single letter, so %d
means an integer (using the decimal base, therefore "d"), %f
means a floating-point number and %s
means a string of characters. Characters other than letters after the %
are modifiers for the format specification and, in particular, numbers are used to specify the requested length of the field on output. So %100s
will format the string to have at least 100 characters, it will pad it with spaces and it will keep it aligned right (in other words, add spaces at the beginning of the string.)
If passed an extra argument, it would use it for that %s
field, so for example printf %100s abc
will print 97 spaces (to get to 100 total, considering the 3 in "abc") followed by the actual string "abc". But if no argument is given, then the format specification is filled with an empty or null argument (which is an empty string for %s
, it would be 0 for %d
, etc.) So that's the same as if an empty string was passed, such as printf %100s ''
. The end result is that only the 100 character padding is printed.
So, putting it all together, printf %100s
results in 100 spaces printed.
Now tr
is a tool to translate characters from input to output. It takes two arguments, SET1 and SET2, each a set of characters, and then translates the first character of SET1 into the first of SET2, the second character of SET1 into the second of SET2 and so on. tr
reads its input from stdin and writes it back to stdout (so it's very useful in pipelines like the one above.) tr
will always translate all occurrences of that character in a given string.
For example, tr aeiou 12345
will translate lowercase vowels into the numbers 1 to 5 in that order, so it will translate "queueing" into "q52523ng" for example. You can also pass it character ranges, such as tr a-z A-Z
to turn any lowercase letter into its corresponding uppercase one.
So tr " " "="
is simply translating spaces into equal signs throughout the string. The first space needs to be quoted to be recognized as an argument. The =
doesn't actually need to be quoted, but doing so doesn't hurt. tr " " =
would have worked the same.
Putting it all together, print 100 spaces, then translate each of them into equal signs.
Hopefully this explains it in enough detail, but if there's still something you don't understand, please leave a comment and I'll try to address that.
Just checking, would the following be more syntactically correct?:printf '%100s' ' ' | tr " " "="
– Vlastimil
yesterday
2
@Vlastimil Actuallyprintf '%100s' ''
, with an empty string... I updated the answer to include that. In this particular case, empty string or a single space wouldn't make a difference, but you can see a difference inprintf '%sxn'
, which is the same asprintf '%sxn' ''
but different fromprintf '%sxn' ' '
. I hope that helps!
– filbranden
yesterday
1
+1 for mention thattr
operates on sets of characters. This is often left out.
– Sergiy Kolodyazhnyy
yesterday
add a comment |
In short, printf %100s
will print 100 spaces, and tr " " "="
will convert those spaces to equal signs, effectively printing 100 equal signs.
Breaking it down:
printf
is a shell built-in. It typically takes two or more arguments, the first of which is a "format string" and the rest will be used to fill up placeholders in that format string. Once that template is fully filled, it will print out the result. If there are more arguments left, it will start over, filling up more arguments and printing the resulting string.
The format string used for printf
takes format specifications, which start with %
and end with a single letter, so %d
means an integer (using the decimal base, therefore "d"), %f
means a floating-point number and %s
means a string of characters. Characters other than letters after the %
are modifiers for the format specification and, in particular, numbers are used to specify the requested length of the field on output. So %100s
will format the string to have at least 100 characters, it will pad it with spaces and it will keep it aligned right (in other words, add spaces at the beginning of the string.)
If passed an extra argument, it would use it for that %s
field, so for example printf %100s abc
will print 97 spaces (to get to 100 total, considering the 3 in "abc") followed by the actual string "abc". But if no argument is given, then the format specification is filled with an empty or null argument (which is an empty string for %s
, it would be 0 for %d
, etc.) So that's the same as if an empty string was passed, such as printf %100s ''
. The end result is that only the 100 character padding is printed.
So, putting it all together, printf %100s
results in 100 spaces printed.
Now tr
is a tool to translate characters from input to output. It takes two arguments, SET1 and SET2, each a set of characters, and then translates the first character of SET1 into the first of SET2, the second character of SET1 into the second of SET2 and so on. tr
reads its input from stdin and writes it back to stdout (so it's very useful in pipelines like the one above.) tr
will always translate all occurrences of that character in a given string.
For example, tr aeiou 12345
will translate lowercase vowels into the numbers 1 to 5 in that order, so it will translate "queueing" into "q52523ng" for example. You can also pass it character ranges, such as tr a-z A-Z
to turn any lowercase letter into its corresponding uppercase one.
So tr " " "="
is simply translating spaces into equal signs throughout the string. The first space needs to be quoted to be recognized as an argument. The =
doesn't actually need to be quoted, but doing so doesn't hurt. tr " " =
would have worked the same.
Putting it all together, print 100 spaces, then translate each of them into equal signs.
Hopefully this explains it in enough detail, but if there's still something you don't understand, please leave a comment and I'll try to address that.
Just checking, would the following be more syntactically correct?:printf '%100s' ' ' | tr " " "="
– Vlastimil
yesterday
2
@Vlastimil Actuallyprintf '%100s' ''
, with an empty string... I updated the answer to include that. In this particular case, empty string or a single space wouldn't make a difference, but you can see a difference inprintf '%sxn'
, which is the same asprintf '%sxn' ''
but different fromprintf '%sxn' ' '
. I hope that helps!
– filbranden
yesterday
1
+1 for mention thattr
operates on sets of characters. This is often left out.
– Sergiy Kolodyazhnyy
yesterday
add a comment |
In short, printf %100s
will print 100 spaces, and tr " " "="
will convert those spaces to equal signs, effectively printing 100 equal signs.
Breaking it down:
printf
is a shell built-in. It typically takes two or more arguments, the first of which is a "format string" and the rest will be used to fill up placeholders in that format string. Once that template is fully filled, it will print out the result. If there are more arguments left, it will start over, filling up more arguments and printing the resulting string.
The format string used for printf
takes format specifications, which start with %
and end with a single letter, so %d
means an integer (using the decimal base, therefore "d"), %f
means a floating-point number and %s
means a string of characters. Characters other than letters after the %
are modifiers for the format specification and, in particular, numbers are used to specify the requested length of the field on output. So %100s
will format the string to have at least 100 characters, it will pad it with spaces and it will keep it aligned right (in other words, add spaces at the beginning of the string.)
If passed an extra argument, it would use it for that %s
field, so for example printf %100s abc
will print 97 spaces (to get to 100 total, considering the 3 in "abc") followed by the actual string "abc". But if no argument is given, then the format specification is filled with an empty or null argument (which is an empty string for %s
, it would be 0 for %d
, etc.) So that's the same as if an empty string was passed, such as printf %100s ''
. The end result is that only the 100 character padding is printed.
So, putting it all together, printf %100s
results in 100 spaces printed.
Now tr
is a tool to translate characters from input to output. It takes two arguments, SET1 and SET2, each a set of characters, and then translates the first character of SET1 into the first of SET2, the second character of SET1 into the second of SET2 and so on. tr
reads its input from stdin and writes it back to stdout (so it's very useful in pipelines like the one above.) tr
will always translate all occurrences of that character in a given string.
For example, tr aeiou 12345
will translate lowercase vowels into the numbers 1 to 5 in that order, so it will translate "queueing" into "q52523ng" for example. You can also pass it character ranges, such as tr a-z A-Z
to turn any lowercase letter into its corresponding uppercase one.
So tr " " "="
is simply translating spaces into equal signs throughout the string. The first space needs to be quoted to be recognized as an argument. The =
doesn't actually need to be quoted, but doing so doesn't hurt. tr " " =
would have worked the same.
Putting it all together, print 100 spaces, then translate each of them into equal signs.
Hopefully this explains it in enough detail, but if there's still something you don't understand, please leave a comment and I'll try to address that.
In short, printf %100s
will print 100 spaces, and tr " " "="
will convert those spaces to equal signs, effectively printing 100 equal signs.
Breaking it down:
printf
is a shell built-in. It typically takes two or more arguments, the first of which is a "format string" and the rest will be used to fill up placeholders in that format string. Once that template is fully filled, it will print out the result. If there are more arguments left, it will start over, filling up more arguments and printing the resulting string.
The format string used for printf
takes format specifications, which start with %
and end with a single letter, so %d
means an integer (using the decimal base, therefore "d"), %f
means a floating-point number and %s
means a string of characters. Characters other than letters after the %
are modifiers for the format specification and, in particular, numbers are used to specify the requested length of the field on output. So %100s
will format the string to have at least 100 characters, it will pad it with spaces and it will keep it aligned right (in other words, add spaces at the beginning of the string.)
If passed an extra argument, it would use it for that %s
field, so for example printf %100s abc
will print 97 spaces (to get to 100 total, considering the 3 in "abc") followed by the actual string "abc". But if no argument is given, then the format specification is filled with an empty or null argument (which is an empty string for %s
, it would be 0 for %d
, etc.) So that's the same as if an empty string was passed, such as printf %100s ''
. The end result is that only the 100 character padding is printed.
So, putting it all together, printf %100s
results in 100 spaces printed.
Now tr
is a tool to translate characters from input to output. It takes two arguments, SET1 and SET2, each a set of characters, and then translates the first character of SET1 into the first of SET2, the second character of SET1 into the second of SET2 and so on. tr
reads its input from stdin and writes it back to stdout (so it's very useful in pipelines like the one above.) tr
will always translate all occurrences of that character in a given string.
For example, tr aeiou 12345
will translate lowercase vowels into the numbers 1 to 5 in that order, so it will translate "queueing" into "q52523ng" for example. You can also pass it character ranges, such as tr a-z A-Z
to turn any lowercase letter into its corresponding uppercase one.
So tr " " "="
is simply translating spaces into equal signs throughout the string. The first space needs to be quoted to be recognized as an argument. The =
doesn't actually need to be quoted, but doing so doesn't hurt. tr " " =
would have worked the same.
Putting it all together, print 100 spaces, then translate each of them into equal signs.
Hopefully this explains it in enough detail, but if there's still something you don't understand, please leave a comment and I'll try to address that.
edited 3 hours ago
Jeff Schaller
39k1053125
39k1053125
answered yesterday
filbranden
7,2552836
7,2552836
Just checking, would the following be more syntactically correct?:printf '%100s' ' ' | tr " " "="
– Vlastimil
yesterday
2
@Vlastimil Actuallyprintf '%100s' ''
, with an empty string... I updated the answer to include that. In this particular case, empty string or a single space wouldn't make a difference, but you can see a difference inprintf '%sxn'
, which is the same asprintf '%sxn' ''
but different fromprintf '%sxn' ' '
. I hope that helps!
– filbranden
yesterday
1
+1 for mention thattr
operates on sets of characters. This is often left out.
– Sergiy Kolodyazhnyy
yesterday
add a comment |
Just checking, would the following be more syntactically correct?:printf '%100s' ' ' | tr " " "="
– Vlastimil
yesterday
2
@Vlastimil Actuallyprintf '%100s' ''
, with an empty string... I updated the answer to include that. In this particular case, empty string or a single space wouldn't make a difference, but you can see a difference inprintf '%sxn'
, which is the same asprintf '%sxn' ''
but different fromprintf '%sxn' ' '
. I hope that helps!
– filbranden
yesterday
1
+1 for mention thattr
operates on sets of characters. This is often left out.
– Sergiy Kolodyazhnyy
yesterday
Just checking, would the following be more syntactically correct?:
printf '%100s' ' ' | tr " " "="
– Vlastimil
yesterday
Just checking, would the following be more syntactically correct?:
printf '%100s' ' ' | tr " " "="
– Vlastimil
yesterday
2
2
@Vlastimil Actually
printf '%100s' ''
, with an empty string... I updated the answer to include that. In this particular case, empty string or a single space wouldn't make a difference, but you can see a difference in printf '%sxn'
, which is the same as printf '%sxn' ''
but different from printf '%sxn' ' '
. I hope that helps!– filbranden
yesterday
@Vlastimil Actually
printf '%100s' ''
, with an empty string... I updated the answer to include that. In this particular case, empty string or a single space wouldn't make a difference, but you can see a difference in printf '%sxn'
, which is the same as printf '%sxn' ''
but different from printf '%sxn' ' '
. I hope that helps!– filbranden
yesterday
1
1
+1 for mention that
tr
operates on sets of characters. This is often left out.– Sergiy Kolodyazhnyy
yesterday
+1 for mention that
tr
operates on sets of characters. This is often left out.– Sergiy Kolodyazhnyy
yesterday
add a comment |
The printf
command uses its first argument as a format for printing its subsequent arguments. printf %100s
prints out its arguments padded to 100 characters wide, using spaces (on the left). There is no argument provided to format, so it formats the empty string once, and outputs 100 spaces. You can see that:
$ printf %100s | hexdump -C
00000000 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |
*
00000064
(20 is the hex for a space; *
means the previous line repeated)
The format strings use approximately the C Xprintf
specifiers: %
, an optional width to fit the formatted value into, and a type of format to use. s
is string formatting, and strings are padded with spaces on the left by default. There could be multiple formats, or other literal parts: printf "a%10sbn" hello
prints
a xb.
tr
replaces selected characters in its standard input with selected replacements, and prints the result to its standard output. tr " " "="
has a single character to be replaced - a space - and a single character to replace it with - an equals sign. It thus turns every space in its input into an =
, and leaves the rest unchanged. You can try that as well:
$ tr " " "="
hello world
hello=world
(I typed the "hello world")
You could have multiple replacements: tr abc def
turns a into d, b into e, c into f, and leaves the rest unchanged. Here it's just a single character, since that was what printf
could cheaply generate.
The pipe |
causes the output of the command on the left, printf %100s
, to be used as the input to the command on the right, tr " " "="
. That is, a hundred consecutive spaces are given to tr
, and each one of them is replaced with an =
, with the new string printed out.
printf %100s | tr " " "="
====================================================================================================
Just checking, would the following be more syntactically correct?:printf '%100s' ' ' | tr " " "="
– Vlastimil
yesterday
1
Formatting a space and padding it with spaces is going to give the same output as formatting an empty string and padding with spaces, but it's not structurally equivalent. Perhaps it's more "correct" in terms of clarity about what's going on, but not syntactically, and they are different commands.
– Michael Homer
yesterday
add a comment |
The printf
command uses its first argument as a format for printing its subsequent arguments. printf %100s
prints out its arguments padded to 100 characters wide, using spaces (on the left). There is no argument provided to format, so it formats the empty string once, and outputs 100 spaces. You can see that:
$ printf %100s | hexdump -C
00000000 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |
*
00000064
(20 is the hex for a space; *
means the previous line repeated)
The format strings use approximately the C Xprintf
specifiers: %
, an optional width to fit the formatted value into, and a type of format to use. s
is string formatting, and strings are padded with spaces on the left by default. There could be multiple formats, or other literal parts: printf "a%10sbn" hello
prints
a xb.
tr
replaces selected characters in its standard input with selected replacements, and prints the result to its standard output. tr " " "="
has a single character to be replaced - a space - and a single character to replace it with - an equals sign. It thus turns every space in its input into an =
, and leaves the rest unchanged. You can try that as well:
$ tr " " "="
hello world
hello=world
(I typed the "hello world")
You could have multiple replacements: tr abc def
turns a into d, b into e, c into f, and leaves the rest unchanged. Here it's just a single character, since that was what printf
could cheaply generate.
The pipe |
causes the output of the command on the left, printf %100s
, to be used as the input to the command on the right, tr " " "="
. That is, a hundred consecutive spaces are given to tr
, and each one of them is replaced with an =
, with the new string printed out.
printf %100s | tr " " "="
====================================================================================================
Just checking, would the following be more syntactically correct?:printf '%100s' ' ' | tr " " "="
– Vlastimil
yesterday
1
Formatting a space and padding it with spaces is going to give the same output as formatting an empty string and padding with spaces, but it's not structurally equivalent. Perhaps it's more "correct" in terms of clarity about what's going on, but not syntactically, and they are different commands.
– Michael Homer
yesterday
add a comment |
The printf
command uses its first argument as a format for printing its subsequent arguments. printf %100s
prints out its arguments padded to 100 characters wide, using spaces (on the left). There is no argument provided to format, so it formats the empty string once, and outputs 100 spaces. You can see that:
$ printf %100s | hexdump -C
00000000 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |
*
00000064
(20 is the hex for a space; *
means the previous line repeated)
The format strings use approximately the C Xprintf
specifiers: %
, an optional width to fit the formatted value into, and a type of format to use. s
is string formatting, and strings are padded with spaces on the left by default. There could be multiple formats, or other literal parts: printf "a%10sbn" hello
prints
a xb.
tr
replaces selected characters in its standard input with selected replacements, and prints the result to its standard output. tr " " "="
has a single character to be replaced - a space - and a single character to replace it with - an equals sign. It thus turns every space in its input into an =
, and leaves the rest unchanged. You can try that as well:
$ tr " " "="
hello world
hello=world
(I typed the "hello world")
You could have multiple replacements: tr abc def
turns a into d, b into e, c into f, and leaves the rest unchanged. Here it's just a single character, since that was what printf
could cheaply generate.
The pipe |
causes the output of the command on the left, printf %100s
, to be used as the input to the command on the right, tr " " "="
. That is, a hundred consecutive spaces are given to tr
, and each one of them is replaced with an =
, with the new string printed out.
printf %100s | tr " " "="
====================================================================================================
The printf
command uses its first argument as a format for printing its subsequent arguments. printf %100s
prints out its arguments padded to 100 characters wide, using spaces (on the left). There is no argument provided to format, so it formats the empty string once, and outputs 100 spaces. You can see that:
$ printf %100s | hexdump -C
00000000 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |
*
00000064
(20 is the hex for a space; *
means the previous line repeated)
The format strings use approximately the C Xprintf
specifiers: %
, an optional width to fit the formatted value into, and a type of format to use. s
is string formatting, and strings are padded with spaces on the left by default. There could be multiple formats, or other literal parts: printf "a%10sbn" hello
prints
a xb.
tr
replaces selected characters in its standard input with selected replacements, and prints the result to its standard output. tr " " "="
has a single character to be replaced - a space - and a single character to replace it with - an equals sign. It thus turns every space in its input into an =
, and leaves the rest unchanged. You can try that as well:
$ tr " " "="
hello world
hello=world
(I typed the "hello world")
You could have multiple replacements: tr abc def
turns a into d, b into e, c into f, and leaves the rest unchanged. Here it's just a single character, since that was what printf
could cheaply generate.
The pipe |
causes the output of the command on the left, printf %100s
, to be used as the input to the command on the right, tr " " "="
. That is, a hundred consecutive spaces are given to tr
, and each one of them is replaced with an =
, with the new string printed out.
printf %100s | tr " " "="
====================================================================================================
edited yesterday
Sergiy Kolodyazhnyy
8,36212152
8,36212152
answered yesterday
Michael Homer
46.3k8121161
46.3k8121161
Just checking, would the following be more syntactically correct?:printf '%100s' ' ' | tr " " "="
– Vlastimil
yesterday
1
Formatting a space and padding it with spaces is going to give the same output as formatting an empty string and padding with spaces, but it's not structurally equivalent. Perhaps it's more "correct" in terms of clarity about what's going on, but not syntactically, and they are different commands.
– Michael Homer
yesterday
add a comment |
Just checking, would the following be more syntactically correct?:printf '%100s' ' ' | tr " " "="
– Vlastimil
yesterday
1
Formatting a space and padding it with spaces is going to give the same output as formatting an empty string and padding with spaces, but it's not structurally equivalent. Perhaps it's more "correct" in terms of clarity about what's going on, but not syntactically, and they are different commands.
– Michael Homer
yesterday
Just checking, would the following be more syntactically correct?:
printf '%100s' ' ' | tr " " "="
– Vlastimil
yesterday
Just checking, would the following be more syntactically correct?:
printf '%100s' ' ' | tr " " "="
– Vlastimil
yesterday
1
1
Formatting a space and padding it with spaces is going to give the same output as formatting an empty string and padding with spaces, but it's not structurally equivalent. Perhaps it's more "correct" in terms of clarity about what's going on, but not syntactically, and they are different commands.
– Michael Homer
yesterday
Formatting a space and padding it with spaces is going to give the same output as formatting an empty string and padding with spaces, but it's not structurally equivalent. Perhaps it's more "correct" in terms of clarity about what's going on, but not syntactically, and they are different commands.
– Michael Homer
yesterday
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f492630%2fexplanation-needed-on-how-i-can-repeat-a-character-in-posix-shell%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown