How to match a leading space with sed (all of them)? I'm not talking about leading tabs, but rather only on leading spaces.

From a small test I did in Nano this seems to be correct:

sed "s/^ //g"

Do you find something wrong with this method?

Note: "All of them" means all leading spaces in the document, in case there are 2 or more, and not just one.

  • 1
    tab is also IN whitespace category. sed "s/^[[:space:]]//g" – RomanPerekhrest Feb 24 '18 at 20:56
  • @RomanPerekhrest So I should go through a paradigm change --- from now and long I shall say "space" for a simple space as with the SPACE key in my keboard and "whitespace" for any space in the general sense (space or tabulation), correct? – user9303970 Feb 24 '18 at 21:16

Remove leading spaces: sed "s/^ *//"

Remove leading whitespace: sed "s/^[[:space:]]*//"

Remove leading spaces and tabs: sed "s/^[ \t]*//" (works in GNU sed) or
sed 's/^[[:blank:]]*//' (works with any sed) or sed $'s/^[ \t]*//' (in ksh/Bash/etc. to give a literal tab to sed)

As said in the comments, the /g specifier does nothing, as the beginning of line appears only once in the line, and even /g does not retry the pattern more than one. You'd need to add a conditional branch explicitly to repeat the substitution: sed -e :a -e 's/^ //' -e ta

^ * matches the empty string (no spaces) too, but that doesn't matter here. If you want to match lines that have at least one space, use ^ * (double space) or ^ + in extended regex. E.g. to change all indentations to exactly two spaces, use sed -e 's/^ */ /' or sed -Ee 's/^ +/ /' (-E is supported in e.g. GNU and FreeBSD)

  • 1
    Note that sed "s/^[ \t]*//" works in GNU sed only if POSIXLY_CORRECT is not in the environment. Otherwise it strips ts and backslashes like other sed implementations. – Stéphane Chazelas Feb 24 '18 at 23:22
  • +1. also worth noting: ` *` matches zero-or-more spaces. ` \+` (basic regex or BRE) or ` +` (extended regex aka ERE, e.g. sed -E, grep -E, awk, perl) matches one-or-more spaces. – cas Feb 24 '18 at 23:45
  • + isn't special in BRE without escaping (see man 7 regex and search for 2nd occurrence of "basic", near end of page). It's the opposite in ERE. The difference between * and + is significant if you're doing anything other than just stripping any leading spaces that may (or may not) be there - ^ * matches all lines, while ^ + matches only lines beginning with space(s). Getting confused by zero-or-more vs one-or-more is fairly common for regex novices like the OP. – cas Feb 25 '18 at 8:21
  • 1
    @cas, quoting from the regex man page at man7.org: "|, +, and ? are ordinary characters and there is no equivalent for their functionality." (though of course there's \{0,1\} and \{1,\}) – ilkkachu Feb 25 '18 at 8:41
  • You're quibbling over a misinterpretation (which is also a pedantic irrelevance) - have you ever seen or used any BRE implementation that doesn't treat escaped +, |, or ? as the equivalent of the same unescaped characters in an ERE? BRE supports \+ as one-or-more, \| as alternation, and \? as zero-or-one. – cas Feb 25 '18 at 8:48

You can do it using below awk command too

 awk '{gsub("^ *","",$0);print $0}' filename

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.