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

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

The simple and obvious solution: sed 's/^ *//;s/ *$//' Many recipes you find online will erroneously add a g flag, but these regular expressions can only match once per line anyway. (In some m...

posted 1y ago by tripleee‭  ·  edited 1y ago by tripleee‭

Answer
#7: Post edited by user avatar tripleee‭ · 2023-07-20T11:54:40Z (over 1 year ago)
Link to cargo cult
  • The simple and obvious solution:
  • ```
  • sed 's/^ *//;s/ *$//'
  • ```
  • Many recipes you find online will erroneously add a `g` flag, but these regular expressions can only match once per line anyway.
  • (In some more detail, `s/from/to/g` says to replace all occurrences of `from` _on the current input line;_ but of course, if you know `from` can only match once, you don't want or need that.)
  • Your requirement to treat the first and last lines differently seems odd to me, but `sed` easily allows you to do that too.
  • ```
  • sed '1s/^ *//;$s/ *$//'
  • ```
  • This adds the address expression `1` to the first command (which matches on line number 1) and the address `$` to the last (which matches the final input line).
  • If your `sed` implementation doesn't support stringing multiple commands together with `;` as shown above, you can pass in the script piecemeal with multiple `-e` options.
  • ```
  • sed -e '1s/^ *//' -e '$s/ *$//'
  • ```
  • The regular expressions above specifically target literal spaces. If you want to target any whitespace, replace each ` ` with `[[:space:]]`, which is a POSIX character class which matches one whitespace character of any kind (space, tab, etc).
  • Something similar could be achieved with Awk with a clever `RS` (record separator) but I'd consider that more obscure, as well as probably slower.
  • The simple and obvious solution:
  • ```
  • sed 's/^ *//;s/ *$//'
  • ```
  • Many recipes you find online will erroneously add a `g` flag, but these regular expressions can only match once per line anyway.
  • (In some more detail, `s/from/to/g` says to replace all occurrences of `from` _on the current input line;_ but of course, if you know `from` can only match once, you don't want or need that. It is harmless as such, of course, but betrays a [cargo cultish](https://en.wikipedia.org/wiki/Cargo_cult) lack of understanding of the construct.)
  • Your requirement to treat the first and last lines differently seems odd to me, but `sed` easily allows you to do that too.
  • ```
  • sed '1s/^ *//;$s/ *$//'
  • ```
  • This adds the address expression `1` to the first command (which matches on line number 1) and the address `$` to the last (which matches the final input line).
  • If your `sed` implementation doesn't support stringing multiple commands together with `;` as shown above, you can pass in the script piecemeal with multiple `-e` options.
  • ```
  • sed -e '1s/^ *//' -e '$s/ *$//'
  • ```
  • The regular expressions above specifically target literal spaces. If you want to target any whitespace, replace each ` ` with `[[:space:]]`, which is a POSIX character class which matches one whitespace character of any kind (space, tab, etc).
  • Something similar could be achieved with Awk with a clever `RS` (record separator) but I'd consider that more obscure, as well as probably slower.
#6: Post edited by user avatar terdon‭ · 2023-07-20T11:46:03Z (over 1 year ago)
Since multiple -e is the standard portable way, I removed the bit saying that is less portable.
  • The simple and obvious solution:
  • ```
  • sed 's/^ *//;s/ *$//'
  • ```
  • Many recipes you find online will erroneously add a `g` flag, but these regular expressions can only match once per line anyway.
  • (In some more detail, `s/from/to/g` says to replace all occurrences of `from` _on the current input line;_ but of course, if you know `from` can only match once, you don't want or need that.)
  • Your requirement to treat the first and last lines differently seems odd to me, but `sed` easily allows you to do that too.
  • ```
  • sed '1s/^ *//;$s/ *$//'
  • ```
  • This adds the address expression `1` to the first command (which matches on line number 1) and the address `$` to the last (which matches the final input line).
  • Many `sed` implementations will allow you to pass in the script piecemeal with multiple `-e` options.
  • ```
  • sed -e '1s/^ *//' -e '$s/ *$//'
  • ```
  • but this is somewhat less portable.
  • The regular expressions above specifically target literal spaces. If you want to target any whitespace, replace each ` ` with `[[:space:]]`, which is a POSIX character class which matches one whitespace character of any kind (space, tab, etc).
  • Something similar could be achieved with Awk with a clever `RS` (record separator) but I'd consider that more obscure, as well as probably slower.
  • The simple and obvious solution:
  • ```
  • sed 's/^ *//;s/ *$//'
  • ```
  • Many recipes you find online will erroneously add a `g` flag, but these regular expressions can only match once per line anyway.
  • (In some more detail, `s/from/to/g` says to replace all occurrences of `from` _on the current input line;_ but of course, if you know `from` can only match once, you don't want or need that.)
  • Your requirement to treat the first and last lines differently seems odd to me, but `sed` easily allows you to do that too.
  • ```
  • sed '1s/^ *//;$s/ *$//'
  • ```
  • This adds the address expression `1` to the first command (which matches on line number 1) and the address `$` to the last (which matches the final input line).
  • If your `sed` implementation doesn't support stringing multiple commands together with `;` as shown above, you can pass in the script piecemeal with multiple `-e` options.
  • ```
  • sed -e '1s/^ *//' -e '$s/ *$//'
  • ```
  • The regular expressions above specifically target literal spaces. If you want to target any whitespace, replace each ` ` with `[[:space:]]`, which is a POSIX character class which matches one whitespace character of any kind (space, tab, etc).
  • Something similar could be achieved with Awk with a clever `RS` (record separator) but I'd consider that more obscure, as well as probably slower.
#5: Post edited by user avatar tripleee‭ · 2023-07-18T06:56:40Z (over 1 year ago)
  • The simple and obvious solution:
  • ```
  • sed 's/^ *//;s/ *$//'
  • ```
  • Many recipes you find online will erroneously add a `g` flag, but these regular expressions can only match once per line anyway.
  • (In some more detail, `s/from/to/g` says to replace all occurrences of `from` _on the current input line;_ but of course, if you know `from` can only match once, you don't want or need that.)
  • Your requirement to treat the first and last lines differently seems odd to me, but `sed` easily allows you to do that too.
  • ```
  • sed '1s/^ *//;$s/ *$//'
  • ```
  • This adds the address expression `1` to the first command (which matches on line number 1) and the address `$` to the last (which matches the final input line).
  • Many `sed` implementations will allow you to pass in the script piecemeal with multiple `-e` options.
  • ```
  • sed -e '1s/^ *//' -e '$s/ *$//'
  • ```
  • but this is somewhat less portable.
  • The regular oxpressions above specifically target literal spaces. If you want to target any whitespace, replace each ` ` with `[[:space:]]`, which is a POSIX character class which matches one whitespace character of any kind (space, tab, etc).
  • Something similar could be achieved with Awk with a clever `RS` (record separator) but I'd consider that more obscure, as well as probably slower.
  • The simple and obvious solution:
  • ```
  • sed 's/^ *//;s/ *$//'
  • ```
  • Many recipes you find online will erroneously add a `g` flag, but these regular expressions can only match once per line anyway.
  • (In some more detail, `s/from/to/g` says to replace all occurrences of `from` _on the current input line;_ but of course, if you know `from` can only match once, you don't want or need that.)
  • Your requirement to treat the first and last lines differently seems odd to me, but `sed` easily allows you to do that too.
  • ```
  • sed '1s/^ *//;$s/ *$//'
  • ```
  • This adds the address expression `1` to the first command (which matches on line number 1) and the address `$` to the last (which matches the final input line).
  • Many `sed` implementations will allow you to pass in the script piecemeal with multiple `-e` options.
  • ```
  • sed -e '1s/^ *//' -e '$s/ *$//'
  • ```
  • but this is somewhat less portable.
  • The regular expressions above specifically target literal spaces. If you want to target any whitespace, replace each ` ` with `[[:space:]]`, which is a POSIX character class which matches one whitespace character of any kind (space, tab, etc).
  • Something similar could be achieved with Awk with a clever `RS` (record separator) but I'd consider that more obscure, as well as probably slower.
#4: Post edited by user avatar tripleee‭ · 2023-07-18T06:55:31Z (over 1 year ago)
[[:space:]] fix, thanks terdon
  • The simple and obvious solution:
  • ```
  • sed 's/^ *//;s/ *$//'
  • ```
  • Many recipes you find online will erroneously add a `g` flag, but these regular expressions can only match once per line anyway.
  • (In some more detail, `s/from/to/g` says to replace all occurrences of `from` _on the current input line;_ but of course, if you know `from` can only match once, you don't want or need that.)
  • Your requirement to treat the first and last lines differently seems odd to me, but `sed` easily allows you to do that too.
  • ```
  • sed '1s/^ *//;$s/ *$//'
  • ```
  • This adds the address expression `1` to the first command (which matches on line number 1) and the address `$` to the last (which matches the final input line).
  • Many `sed` implementations will allow you to pass in the script piecemeal with multiple `-e` options.
  • ```
  • sed -e '1s/^ *//' -e '$s/ *$//'
  • ```
  • but this is somewhat less portable.
  • Something similar could be achieved with Awk with a clever `RS` (record separator) but I'd consider that more obscure, as well as probably slower.
  • The simple and obvious solution:
  • ```
  • sed 's/^ *//;s/ *$//'
  • ```
  • Many recipes you find online will erroneously add a `g` flag, but these regular expressions can only match once per line anyway.
  • (In some more detail, `s/from/to/g` says to replace all occurrences of `from` _on the current input line;_ but of course, if you know `from` can only match once, you don't want or need that.)
  • Your requirement to treat the first and last lines differently seems odd to me, but `sed` easily allows you to do that too.
  • ```
  • sed '1s/^ *//;$s/ *$//'
  • ```
  • This adds the address expression `1` to the first command (which matches on line number 1) and the address `$` to the last (which matches the final input line).
  • Many `sed` implementations will allow you to pass in the script piecemeal with multiple `-e` options.
  • ```
  • sed -e '1s/^ *//' -e '$s/ *$//'
  • ```
  • but this is somewhat less portable.
  • The regular oxpressions above specifically target literal spaces. If you want to target any whitespace, replace each ` ` with `[[:space:]]`, which is a POSIX character class which matches one whitespace character of any kind (space, tab, etc).
  • Something similar could be achieved with Awk with a clever `RS` (record separator) but I'd consider that more obscure, as well as probably slower.
#3: Post edited by user avatar tripleee‭ · 2023-07-12T13:11:54Z (over 1 year ago)
Multiple -e options
  • The simple and obvious solution:
  • ```
  • sed 's/^ *//;s/ *$//'
  • ```
  • Many recipes you find online will erroneously add a `g` flag, but these regular expressions can only match once per line anyway.
  • (In some more detail, `s/from/to/g` says to replace all occurrences of `from` _on the current input line;_ but of course, if you know `from` can only match once, you don't want or need that.)
  • Your requirement to treat the first and last lines differently seems odd to me, but `sed` easily allows you to do that too.
  • ```
  • sed `1s/^ *//;$s/ *$//'
  • ```
  • This adds the address expression `1` to the first command (which matches on line number 1) and the address `$` to the last (which matches the final input line).
  • Something similar could be achieved with Awk with a clever `RS` (record separator) but I'd consider that more obscure, as well as probably slower.
  • The simple and obvious solution:
  • ```
  • sed 's/^ *//;s/ *$//'
  • ```
  • Many recipes you find online will erroneously add a `g` flag, but these regular expressions can only match once per line anyway.
  • (In some more detail, `s/from/to/g` says to replace all occurrences of `from` _on the current input line;_ but of course, if you know `from` can only match once, you don't want or need that.)
  • Your requirement to treat the first and last lines differently seems odd to me, but `sed` easily allows you to do that too.
  • ```
  • sed '1s/^ *//;$s/ *$//'
  • ```
  • This adds the address expression `1` to the first command (which matches on line number 1) and the address `$` to the last (which matches the final input line).
  • Many `sed` implementations will allow you to pass in the script piecemeal with multiple `-e` options.
  • ```
  • sed -e '1s/^ *//' -e '$s/ *$//'
  • ```
  • but this is somewhat less portable.
  • Something similar could be achieved with Awk with a clever `RS` (record separator) but I'd consider that more obscure, as well as probably slower.
#2: Post edited by user avatar mauke‭ · 2023-07-12T13:09:19Z (over 1 year ago)
  • The simple and obvious solution:
  • ```
  • sed 's/^ *//;s/ *$//'
  • ```
  • Many recipes you find online will erroneously add a `g` flag, but these regular expressions can only match once per line anyway.
  • (In some more detail, `s/from/to/g` says to replace all occurrences of `from` _on the current input line;_ but of course, if you know `from` can only match once, you don't want or need that.)
  • Your requirement to treat the first and last lines differently seems odd to me, but `sed` easily allows you to do that too.
  • ```
  • sed `1s/^ *//;$s/ *//'
  • ```
  • This adds the address expression `1` to the first command (which matches on line number 1) and the address `$` to the last (which matches the final input line).
  • Something similar could be achieved with Awk with a clever `RS` (record separator) but I'd consider that more obscure, as well as probably slower.
  • The simple and obvious solution:
  • ```
  • sed 's/^ *//;s/ *$//'
  • ```
  • Many recipes you find online will erroneously add a `g` flag, but these regular expressions can only match once per line anyway.
  • (In some more detail, `s/from/to/g` says to replace all occurrences of `from` _on the current input line;_ but of course, if you know `from` can only match once, you don't want or need that.)
  • Your requirement to treat the first and last lines differently seems odd to me, but `sed` easily allows you to do that too.
  • ```
  • sed `1s/^ *//;$s/ *$//'
  • ```
  • This adds the address expression `1` to the first command (which matches on line number 1) and the address `$` to the last (which matches the final input line).
  • Something similar could be achieved with Awk with a clever `RS` (record separator) but I'd consider that more obscure, as well as probably slower.
#1: Initial revision by user avatar tripleee‭ · 2023-07-11T07:53:48Z (over 1 year ago)
The simple and obvious solution:

```
sed 's/^ *//;s/ *$//'
```

Many recipes you find online will erroneously add a `g` flag, but these regular expressions can only match once per line anyway.

(In some more detail, `s/from/to/g` says to replace all occurrences of `from` _on the current input line;_ but of course, if you know `from` can only match once, you don't want or need that.)

Your requirement to treat the first and last lines differently seems odd to me, but `sed` easily allows you to do that too.

```
sed `1s/^ *//;$s/ *//'
```
This adds the address expression `1` to the first command (which matches on line number 1) and the address `$` to the last (which matches the final input line).

Something similar could be achieved with Awk with a clever `RS` (record separator) but I'd consider that more obscure, as well as probably slower.