Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Post History

60%
+1 −0
Q&A Simplest way of stripping leading/trailing whitespace from file or program output

If I understand you correctly, you want to skip empty lines at the beginning of a file/stream strip leading and trailing whitespace of non-empty lines skip empty lines at the end of a file/str...

posted 10mo ago by AdminBee‭  ·  edited 9mo ago by AdminBee‭

Answer
#8: Post edited by user avatar AdminBee‭ · 2023-08-01T08:22:52Z (9 months ago)
Use same script name throughout
  • If I understand you correctly, you want to
  • * skip empty lines at the beginning of a file/stream
  • * strip leading and trailing whitespace of non-empty lines
  • * skip empty lines at the end of a file/stream.[]()
  • This can be achieved using the following `awk` program:
  • ```lang-bash
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {printf "%s",buf;buf=""};sub(/^[[:blank:]]*/,"");sub(/[[:blank:]]*$/,"")}1'
  • ```
  • This will do the following
  • 1. If the line is (visually) empty, i.e. contains only space or nothing at all, it checks if a position flag `m` (for "main") is set. If set, a "newline" is added to a buffer variable `buf`. If not, the line is simply ignored and processing skipped to the `next` line.
  • 2. If the line was not skipped, it is non-empty.
  • * In that case, if the flag `m` was not yet set the program has now reached the "main" part, so `m` is set to 1. Otherwise, it was already in the main part, and any buffered empty lines need to be printed now (but the buffer cleared). If there were no buffered empty lines, `buf` will be empty and nothing printed, hence no harm done.
  • * Then use `sub()` to strip the leading and trailing whitespace from the line.
  • * The seemingly stray `1` outside of the action blocks instructs `awk` to print the current line including all modifications made.
  • This ensures that leading and trailing empty lines are omitted while keeping (but if necessary sanitizing) internal empty lines.
  • If you want to omit trimming of the non-empty lines, you can simply skip the two calls to `sub()`.
  • ---
  • This approach can be made more comfortable by placing the program in an `awk` script, say `strip_wsp.awk`:
  • ```lang-awk
  • #!/usr/bin/awk -f
  • NF==0{
  • if (m) {buf=buf RS}
  • next
  • }
  • {
  • if (!m) {m=1} else {printf "%s",buf;buf=""}
  • if (trimlines) {
  • sub(/^[[:blank:]]*/,"")
  • sub(/[[:blank:]]*$/,"")
  • }
  • }
  • 1
  • ```
  • This version allows you to define an `awk` variable `trimlines` which, if set to non-zero, trims non-empty lines, but by default would leave them untouched:
  • Applied to a somewhat expanded version of your example string, the result is like this:
  • ```lang-shellsession
  • $ printf -- "
  • hello
  • mellow
  • world
  • " | awk -v trimlines=1 -f trim_wsp.awk
  • hello
  • mellow
  • world
  • ```
  • If I understand you correctly, you want to
  • * skip empty lines at the beginning of a file/stream
  • * strip leading and trailing whitespace of non-empty lines
  • * skip empty lines at the end of a file/stream.[]()
  • This can be achieved using the following `awk` program:
  • ```lang-bash
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {printf "%s",buf;buf=""};sub(/^[[:blank:]]*/,"");sub(/[[:blank:]]*$/,"")}1'
  • ```
  • This will do the following
  • 1. If the line is (visually) empty, i.e. contains only space or nothing at all, it checks if a position flag `m` (for "main") is set. If set, a "newline" is added to a buffer variable `buf`. If not, the line is simply ignored and processing skipped to the `next` line.
  • 2. If the line was not skipped, it is non-empty.
  • * In that case, if the flag `m` was not yet set the program has now reached the "main" part, so `m` is set to 1. Otherwise, it was already in the main part, and any buffered empty lines need to be printed now (but the buffer cleared). If there were no buffered empty lines, `buf` will be empty and nothing printed, hence no harm done.
  • * Then use `sub()` to strip the leading and trailing whitespace from the line.
  • * The seemingly stray `1` outside of the action blocks instructs `awk` to print the current line including all modifications made.
  • This ensures that leading and trailing empty lines are omitted while keeping (but if necessary sanitizing) internal empty lines.
  • If you want to omit trimming of the non-empty lines, you can simply skip the two calls to `sub()`.
  • ---
  • This approach can be made more comfortable by placing the program in an `awk` script, say `strip_wsp.awk`:
  • ```lang-awk
  • #!/usr/bin/awk -f
  • NF==0{
  • if (m) {buf=buf RS}
  • next
  • }
  • {
  • if (!m) {m=1} else {printf "%s",buf;buf=""}
  • if (trimlines) {
  • sub(/^[[:blank:]]*/,"")
  • sub(/[[:blank:]]*$/,"")
  • }
  • }
  • 1
  • ```
  • This version allows you to define an `awk` variable `trimlines` which, if set to non-zero, trims non-empty lines, but by default would leave them untouched:
  • Applied to a somewhat expanded version of your example string, the result is like this:
  • ```lang-shellsession
  • $ printf -- "
  • hello
  • mellow
  • world
  • " | awk -v trimlines=1 -f strip_wsp.awk
  • hello
  • mellow
  • world
  • ```
#7: Post edited by user avatar AdminBee‭ · 2023-07-31T14:51:21Z (9 months ago)
Updated command
  • If I understand you correctly, you want to
  • * skip empty lines at the beginning of a file/stream
  • * strip leading and trailing whitespace of non-empty lines
  • * skip empty lines at the end of a file/stream.[]()
  • This can be achieved using the following `awk` program:
  • ```lang-bash
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:blank:]]*/,"");sub(/[[:blank:]]*$/,"")}1'
  • ```
  • This will do the following
  • 1. If the line is (visually) empty, i.e. contains only space or nothing at all, it checks if a position flag `m` (for "main") is set. If set, a "newline" is added to a buffer variable `buf`. If not, the line is simply ignored and processing skipped to the `next` line.
  • 2. If the line was not skipped, it is non-empty.
  • * In that case, if the flag `m` was not yet set the program has now reached the "main" part, so `m` is set to 1. Otherwise, it was already in the main part, and any buffered empty lines need to be printed now (but the buffer cleared). If there were no buffered empty lines, `buf` will be empty and nothing printed, hence no harm done.
  • * Then use `sub()` to strip the leading and trailing whitespace from the line.
  • * The seemingly stray `1` outside of the action blocks instructs `awk` to print the current line including all modifications made.
  • This ensures that leading and trailing empty lines are omitted while keeping (but if necessary sanitizing) internal empty lines.
  • If you want to omit trimming of the non-empty lines, you can simply skip the two calls to `sub()`.
  • ---
  • This approach can be made more comfortable by placing the program in an `awk` script, say `strip_wsp.awk`:
  • ```lang-awk
  • #!/usr/bin/awk -f
  • NF==0{
  • if (m) {buf=buf RS}
  • next
  • }
  • {
  • if (!m) {m=1} else {print buf;buf=""}
  • if (trimlines) {
  • sub(/^[[:blank:]]*/,"")
  • sub(/[[:blank:]]*$/,"")
  • }
  • }
  • 1
  • ```
  • This version allows you to define an `awk` variable `trimlines` which, if set to non-zero, trims non-empty lines, but by default would leave them untouched:
  • Applied to a somewhat expanded version of your example string, the result is like this:
  • ```lang-shellsession
  • $ printf -- "\n \n hello\nmellow \n \n\nworld\n\n\n" | awk -v trimlines=1 -f trim_wsp.awk
  • hello
  • mellow
  • world
  • ```
  • If I understand you correctly, you want to
  • * skip empty lines at the beginning of a file/stream
  • * strip leading and trailing whitespace of non-empty lines
  • * skip empty lines at the end of a file/stream.[]()
  • This can be achieved using the following `awk` program:
  • ```lang-bash
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {printf "%s",buf;buf=""};sub(/^[[:blank:]]*/,"");sub(/[[:blank:]]*$/,"")}1'
  • ```
  • This will do the following
  • 1. If the line is (visually) empty, i.e. contains only space or nothing at all, it checks if a position flag `m` (for "main") is set. If set, a "newline" is added to a buffer variable `buf`. If not, the line is simply ignored and processing skipped to the `next` line.
  • 2. If the line was not skipped, it is non-empty.
  • * In that case, if the flag `m` was not yet set the program has now reached the "main" part, so `m` is set to 1. Otherwise, it was already in the main part, and any buffered empty lines need to be printed now (but the buffer cleared). If there were no buffered empty lines, `buf` will be empty and nothing printed, hence no harm done.
  • * Then use `sub()` to strip the leading and trailing whitespace from the line.
  • * The seemingly stray `1` outside of the action blocks instructs `awk` to print the current line including all modifications made.
  • This ensures that leading and trailing empty lines are omitted while keeping (but if necessary sanitizing) internal empty lines.
  • If you want to omit trimming of the non-empty lines, you can simply skip the two calls to `sub()`.
  • ---
  • This approach can be made more comfortable by placing the program in an `awk` script, say `strip_wsp.awk`:
  • ```lang-awk
  • #!/usr/bin/awk -f
  • NF==0{
  • if (m) {buf=buf RS}
  • next
  • }
  • {
  • if (!m) {m=1} else {printf "%s",buf;buf=""}
  • if (trimlines) {
  • sub(/^[[:blank:]]*/,"")
  • sub(/[[:blank:]]*$/,"")
  • }
  • }
  • 1
  • ```
  • This version allows you to define an `awk` variable `trimlines` which, if set to non-zero, trims non-empty lines, but by default would leave them untouched:
  • Applied to a somewhat expanded version of your example string, the result is like this:
  • ```lang-shellsession
  • $ printf -- "\n \n hello\nmellow \n \n\nworld\n\n\n" | awk -v trimlines=1 -f trim_wsp.awk
  • hello
  • mellow
  • world
  • ```
#6: Post edited by user avatar AdminBee‭ · 2023-07-14T09:45:37Z (10 months ago)
Add script-file solution for convenience
  • If I understand you correctly, you want to
  • * skip empty lines at the beginning of a file/stream
  • * strip leading and trailing whitespace of non-empty lines
  • * skip empty lines at the end of a file/stream.[]()
  • This can be achieved using the following `awk` program:
  • ```lang-bash
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:blank:]]*/,"");sub(/[[:blank:]]*$/,"")}1'
  • ```
  • This will do the following
  • 1. If the line is (visually) empty, i.e. contains only space or nothing at all, it checks if a position flag `m` (for "main") is set. If set, a "newline" is added to a buffer variable `buf`. If not, the line is simply ignored and processing skipped to the `next` line.
  • 2. If the line was not skipped, it is non-empty.
  • * In that case, if the flag `m` was not yet set the program has now reached the "main" part, so `m` is set to 1. Otherwise, it was already in the main part, and any buffered empty lines need to be printed now (but the buffer cleared). If there were no buffered empty lines, `buf` will be empty and nothing printed, hence no harm done.
  • * Then use `sub()` to strip the leading and trailing whitespace from the line.
  • * The seemingly stray `1` outside of the action blocks instructs `awk` to print the current line including all modifications made.
  • This ensures that leading and trailing empty lines are omitted while keeping (but if necessary sanitizing) internal empty lines.
  • If you want to omit trimming of the non-empty lines, you can simply skip the two calls to `sub()`.
  • Applied to a somewhat expanded version of your example string, the result is like this:
  • ```lang-shellsession
  • $ printf -- "
  • hello
  • mellow
  • world
  • " |
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:blank:]]*/,"");sub(/[[:blank:]]*$/,"")}1'
  • hello
  • mellow
  • world
  • ```
  • If I understand you correctly, you want to
  • * skip empty lines at the beginning of a file/stream
  • * strip leading and trailing whitespace of non-empty lines
  • * skip empty lines at the end of a file/stream.[]()
  • This can be achieved using the following `awk` program:
  • ```lang-bash
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:blank:]]*/,"");sub(/[[:blank:]]*$/,"")}1'
  • ```
  • This will do the following
  • 1. If the line is (visually) empty, i.e. contains only space or nothing at all, it checks if a position flag `m` (for "main") is set. If set, a "newline" is added to a buffer variable `buf`. If not, the line is simply ignored and processing skipped to the `next` line.
  • 2. If the line was not skipped, it is non-empty.
  • * In that case, if the flag `m` was not yet set the program has now reached the "main" part, so `m` is set to 1. Otherwise, it was already in the main part, and any buffered empty lines need to be printed now (but the buffer cleared). If there were no buffered empty lines, `buf` will be empty and nothing printed, hence no harm done.
  • * Then use `sub()` to strip the leading and trailing whitespace from the line.
  • * The seemingly stray `1` outside of the action blocks instructs `awk` to print the current line including all modifications made.
  • This ensures that leading and trailing empty lines are omitted while keeping (but if necessary sanitizing) internal empty lines.
  • If you want to omit trimming of the non-empty lines, you can simply skip the two calls to `sub()`.
  • ---
  • This approach can be made more comfortable by placing the program in an `awk` script, say `strip_wsp.awk`:
  • ```lang-awk
  • #!/usr/bin/awk -f
  • NF==0{
  • if (m) {buf=buf RS}
  • next
  • }
  • {
  • if (!m) {m=1} else {print buf;buf=""}
  • if (trimlines) {
  • sub(/^[[:blank:]]*/,"")
  • sub(/[[:blank:]]*$/,"")
  • }
  • }
  • 1
  • ```
  • This version allows you to define an `awk` variable `trimlines` which, if set to non-zero, trims non-empty lines, but by default would leave them untouched:
  • Applied to a somewhat expanded version of your example string, the result is like this:
  • ```lang-shellsession
  • $ printf -- "
  • hello
  • mellow
  • world
  • " | awk -v trimlines=1 -f trim_wsp.awk
  • hello
  • mellow
  • world
  • ```
#5: Post edited by user avatar AdminBee‭ · 2023-07-13T08:05:45Z (10 months ago)
Include note on how to turn off whitespace-trimming on the non-empty lines. Use [:blank:] instead of [:space:] since only horizontal whitespace is to be trimmed there.
  • If I understand you correctly, you want to
  • * skip empty lines at the beginning of a file/stream
  • * strip leading and trailing whitespace of non-empty lines
  • * skip empty lines at the end of a file/stream.[]()
  • This can be achieved using the following `awk` program:
  • ```lang-bash
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
  • ```
  • This will do the following
  • 1. If the line is (visually) empty, i.e. contains only space or nothing at all, it checks if a position flag `m` (for "main") is set. If set, a "newline" is added to a buffer variable `buf`. If not, the line is simply ignored and processing skipped to the `next` line.
  • 2. If the line was not skipped, it is non-empty.
  • * In that case, if the flag `m` was not yet set the program has now reached the "main" part, so `m` is set to 1. Otherwise, it was already in the main part, and any buffered empty lines need to be printed now (but the buffer cleared). If there were no buffered empty lines, `buf` will be empty and nothing printed, hence no harm done.
  • * Then use `sub()` to strip the leading and trailing whitespace from the line.
  • * The seemingly stray `1` outside of the action blocks instructs `awk` to print the current line including all modifications made.
  • This ensures that leading and trailing empty lines are omitted while keeping (but if necessary sanitizing) internal empty lines.
  • Applied to a somewhat expanded version of your example string, the result is like this:
  • ```lang-shellsession
  • $ printf -- "\n \n hello\nmellow \n \n\nworld\n\n\n" |
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
  • hello
  • mellow
  • world
  • ```
  • If I understand you correctly, you want to
  • * skip empty lines at the beginning of a file/stream
  • * strip leading and trailing whitespace of non-empty lines
  • * skip empty lines at the end of a file/stream.[]()
  • This can be achieved using the following `awk` program:
  • ```lang-bash
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:blank:]]*/,"");sub(/[[:blank:]]*$/,"")}1'
  • ```
  • This will do the following
  • 1. If the line is (visually) empty, i.e. contains only space or nothing at all, it checks if a position flag `m` (for "main") is set. If set, a "newline" is added to a buffer variable `buf`. If not, the line is simply ignored and processing skipped to the `next` line.
  • 2. If the line was not skipped, it is non-empty.
  • * In that case, if the flag `m` was not yet set the program has now reached the "main" part, so `m` is set to 1. Otherwise, it was already in the main part, and any buffered empty lines need to be printed now (but the buffer cleared). If there were no buffered empty lines, `buf` will be empty and nothing printed, hence no harm done.
  • * Then use `sub()` to strip the leading and trailing whitespace from the line.
  • * The seemingly stray `1` outside of the action blocks instructs `awk` to print the current line including all modifications made.
  • This ensures that leading and trailing empty lines are omitted while keeping (but if necessary sanitizing) internal empty lines.
  • If you want to omit trimming of the non-empty lines, you can simply skip the two calls to `sub()`.
  • Applied to a somewhat expanded version of your example string, the result is like this:
  • ```lang-shellsession
  • $ printf -- "\n \n hello\nmellow \n \n\nworld\n\n\n" |
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:blank:]]*/,"");sub(/[[:blank:]]*$/,"")}1'
  • hello
  • mellow
  • world
  • ```
#4: Post edited by user avatar AdminBee‭ · 2023-07-12T13:13:06Z (10 months ago)
Break text for readability
  • If I understand you correctly, you want to
  • * skip empty lines at the beginning of a file/stream
  • * strip leading and trailing whitespace of non-empty lines
  • * skip empty lines at the end of a file/stream.[]()
  • This can be achieved using the following `awk` program:
  • ```lang-bash
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
  • ```
  • This will do the following
  • 1. If the line is (visually) empty, i.e. contains only space or nothing at all, it checks if a position flag `m` (for "main") is set. If set, a "newline" is added to a buffer variable `buf`. If not, the line is simply ignored and processing skipped to the `next` line.
  • 2. If the line was not skipped, it is non-empty.
  • * In that case, if the flag `m` was not yet set the program has now reached the "main" part, so `m` is set to 1. Otherwise, it was already in the main part, and any buffered empty lines need to be printed now (but the buffer cleared). If there were no buffered empty lines, `buf` will be empty and nothing printed, hence no harm done.
  • * Then use `sub()` to strip the leading and trailing whitespace from the line.
  • * The seemingly stray `1` outside of the action blocks instructs `awk` to print the current line including all modifications made.
  • This ensures that leading and trailing empty lines are omitted while keeping (but if necessary sanitizing) internal empty lines.
  • Applied to a somewhat expanded version of your example string, the result is like this:
  • ```lang-shellsession
  • $ printf -- "
  • hello
  • mellow
  • world
  • " | awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
  • hello
  • mellow
  • world
  • ```
  • If I understand you correctly, you want to
  • * skip empty lines at the beginning of a file/stream
  • * strip leading and trailing whitespace of non-empty lines
  • * skip empty lines at the end of a file/stream.[]()
  • This can be achieved using the following `awk` program:
  • ```lang-bash
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
  • ```
  • This will do the following
  • 1. If the line is (visually) empty, i.e. contains only space or nothing at all, it checks if a position flag `m` (for "main") is set. If set, a "newline" is added to a buffer variable `buf`. If not, the line is simply ignored and processing skipped to the `next` line.
  • 2. If the line was not skipped, it is non-empty.
  • * In that case, if the flag `m` was not yet set the program has now reached the "main" part, so `m` is set to 1. Otherwise, it was already in the main part, and any buffered empty lines need to be printed now (but the buffer cleared). If there were no buffered empty lines, `buf` will be empty and nothing printed, hence no harm done.
  • * Then use `sub()` to strip the leading and trailing whitespace from the line.
  • * The seemingly stray `1` outside of the action blocks instructs `awk` to print the current line including all modifications made.
  • This ensures that leading and trailing empty lines are omitted while keeping (but if necessary sanitizing) internal empty lines.
  • Applied to a somewhat expanded version of your example string, the result is like this:
  • ```lang-shellsession
  • $ printf -- "
  • hello
  • mellow
  • world
  • " |
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
  • hello
  • mellow
  • world
  • ```
#3: Post edited by user avatar AdminBee‭ · 2023-07-12T13:05:13Z (10 months ago)
One prompt is enough
  • If I understand you correctly, you want to
  • * skip empty lines at the beginning of a file/stream
  • * strip leading and trailing whitespace of non-empty lines
  • * skip empty lines at the end of a file/stream.[]()
  • This can be achieved using the following `awk` program:
  • ```lang-bash
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
  • ```
  • This will do the following
  • 1. If the line is (visually) empty, i.e. contains only space or nothing at all, it checks if a position flag `m` (for "main") is set. If set, a "newline" is added to a buffer variable `buf`. If not, the line is simply ignored and processing skipped to the `next` line.
  • 2. If the line was not skipped, it is non-empty.
  • * In that case, if the flag `m` was not yet set the program has now reached the "main" part, so `m` is set to 1. Otherwise, it was already in the main part, and any buffered empty lines need to be printed now (but the buffer cleared). If there were no buffered empty lines, `buf` will be empty and nothing printed, hence no harm done.
  • * Then use `sub()` to strip the leading and trailing whitespace from the line.
  • * The seemingly stray `1` outside of the action blocks instructs `awk` to print the current line including all modifications made.
  • This ensures that leading and trailing empty lines are omitted while keeping (but if necessary sanitizing) internal empty lines.
  • Applied to a somewhat expanded version of your example string, the result is like this:
  • ```lang-shellsession
  • $ > printf -- "
  • hello
  • mellow
  • world
  • " | awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
  • hello
  • mellow
  • world
  • ```
  • If I understand you correctly, you want to
  • * skip empty lines at the beginning of a file/stream
  • * strip leading and trailing whitespace of non-empty lines
  • * skip empty lines at the end of a file/stream.[]()
  • This can be achieved using the following `awk` program:
  • ```lang-bash
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
  • ```
  • This will do the following
  • 1. If the line is (visually) empty, i.e. contains only space or nothing at all, it checks if a position flag `m` (for "main") is set. If set, a "newline" is added to a buffer variable `buf`. If not, the line is simply ignored and processing skipped to the `next` line.
  • 2. If the line was not skipped, it is non-empty.
  • * In that case, if the flag `m` was not yet set the program has now reached the "main" part, so `m` is set to 1. Otherwise, it was already in the main part, and any buffered empty lines need to be printed now (but the buffer cleared). If there were no buffered empty lines, `buf` will be empty and nothing printed, hence no harm done.
  • * Then use `sub()` to strip the leading and trailing whitespace from the line.
  • * The seemingly stray `1` outside of the action blocks instructs `awk` to print the current line including all modifications made.
  • This ensures that leading and trailing empty lines are omitted while keeping (but if necessary sanitizing) internal empty lines.
  • Applied to a somewhat expanded version of your example string, the result is like this:
  • ```lang-shellsession
  • $ printf -- "
  • hello
  • mellow
  • world
  • " | awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
  • hello
  • mellow
  • world
  • ```
#2: Post edited by user avatar AdminBee‭ · 2023-07-12T13:04:39Z (10 months ago)
Make explanation clearer
  • If I understand you correctly, you want to strip
  • * empty lines at the beginning of a file/stream
  • * leading and trailing whitespace of non-empty lines
  • * empty lines at the end of a file/stream
  • This can be achieved using the following `awk` program:
  • ```lang-bash
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
  • ```
  • This will do the following
  • 1. If the line is (visually) empty, i.e. contains only space or nothing at all, it checks if a position flag `m` (for "main") is set. If set, a "newline" is added to a buffer variable `buf`. If not, the line is simply ignored and processing skipped to the `next` line.
  • 2. If the line was not skipped, it is non-empty.
  • * In that case, if the flag `m` was not yet set the program has now reached the "main" part, so `m` is set to 1. Otherwise, it was already in the main part, and any buffered empty lines need to be printed now (but the buffer cleared). If there were no buffered empty lines, `buf` will be empty and nothing printed, hence no harm done.
  • * Then use `sub()` to strip the leading and trailing whitespace from the line.
  • * The seemingly stray `1` outside of the action blocks instructs `awk` to print the current line including all modifications made.
  • This ensures that leading and trailing empty lines are omitted while keeping (but if necessary sanitizing) internal empty lines.
  • Applied to a somewhat expanded version of your example string, the result is like this:
  • ```lang-shellsession
  • $ > printf -- "\n \n hello\nmellow \n \n\nworld\n\n\n" | awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
  • hello
  • mellow
  • world
  • ```
  • If I understand you correctly, you want to
  • * skip empty lines at the beginning of a file/stream
  • * strip leading and trailing whitespace of non-empty lines
  • * skip empty lines at the end of a file/stream.[]()
  • This can be achieved using the following `awk` program:
  • ```lang-bash
  • awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
  • ```
  • This will do the following
  • 1. If the line is (visually) empty, i.e. contains only space or nothing at all, it checks if a position flag `m` (for "main") is set. If set, a "newline" is added to a buffer variable `buf`. If not, the line is simply ignored and processing skipped to the `next` line.
  • 2. If the line was not skipped, it is non-empty.
  • * In that case, if the flag `m` was not yet set the program has now reached the "main" part, so `m` is set to 1. Otherwise, it was already in the main part, and any buffered empty lines need to be printed now (but the buffer cleared). If there were no buffered empty lines, `buf` will be empty and nothing printed, hence no harm done.
  • * Then use `sub()` to strip the leading and trailing whitespace from the line.
  • * The seemingly stray `1` outside of the action blocks instructs `awk` to print the current line including all modifications made.
  • This ensures that leading and trailing empty lines are omitted while keeping (but if necessary sanitizing) internal empty lines.
  • Applied to a somewhat expanded version of your example string, the result is like this:
  • ```lang-shellsession
  • $ > printf -- "\n \n hello\nmellow \n \n\nworld\n\n\n" | awk 'NF==0{if (m) {buf=buf RS}; next}
  • {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
  • hello
  • mellow
  • world
  • ```
#1: Initial revision by user avatar AdminBee‭ · 2023-07-12T13:03:52Z (10 months ago)
If I understand you correctly, you want to strip
* empty lines at the beginning of a file/stream
* leading and trailing whitespace of non-empty lines
* empty lines at the end of a file/stream

This can be achieved using the following `awk` program:
```lang-bash
awk 'NF==0{if (m) {buf=buf RS}; next}
          {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
```
This will do the following
1. If the line is (visually) empty, i.e. contains only space or nothing at all, it checks if a position flag `m` (for "main") is set. If set, a "newline" is added to a buffer variable `buf`. If not, the line is simply ignored and processing skipped to the `next` line.
2. If the line was not skipped, it is non-empty.
   * In that case, if the flag `m` was not yet set the program has now reached the "main" part, so `m` is set to 1. Otherwise, it was already in the main part, and any buffered empty lines need to be printed now (but the buffer cleared). If there were no buffered empty lines, `buf` will be empty and nothing printed, hence no harm done.
   * Then use `sub()` to strip the leading and trailing whitespace from the line.
   * The seemingly stray `1` outside of the action blocks instructs `awk` to print the current line including all modifications made.

This ensures that leading and trailing empty lines are omitted while keeping (but if necessary sanitizing) internal empty lines.


Applied to a somewhat expanded version of your example string, the result is like this:
```lang-shellsession
$ > printf -- "\n \n hello\nmellow \n \n\nworld\n\n\n" | awk 'NF==0{if (m) {buf=buf RS}; next}
          {if (!m) {m=1} else {print buf;buf=""};sub(/^[[:space:]]*/,"");sub(/[[:space:]]*$/,"")}1'
hello

mellow



world
```