29

I found a question about, how to remove lines longer then 2048 chars:

How to delete line if longer than XY?

Q: But how can I remove lines shorter then 4 chars? So remove lines that has 1 or 2 or 3 length in a file.

UPDATE: Thanks for the many GOOD answers, but I can only mark one as OK

42

You could use sed. The following would remove lines that are 3 characters long or smaller:

sed -r '/^.{,3}$/d' filename

In order to save the changes to the file in-place, supply the -i option.

If your version of sed doesn't support extended RE syntax, then you could write the same in BRE:

sed '/^.\{,3\}$/d' filename

which would work with all sed variants.


You could also use awk:

awk 'length($0)>3' filename

Using perl:

perl -lne 'length()>3 && print' filename
  • sed '/^.\{,3\}$/d' doesn't work with BSD sed: sed: 1: "/^.\{,3\}$/d": RE error: invalid repetition count(s). The sed -r version is syntactically valid, but won't remove lines. – Dereckson Feb 18 '18 at 14:50
5

Some more variations:

grep .... file

or

sed '/..../!d' file

or

sed -n 's/./&/4p' file

or

awk 'gsub(/./,"&")>3' file

or

awk 'length>3' file

or GNU awk:

awk 'NF>3' FS= file
  • 1
    Oh that grep .... is so elegant! – grofte May 15 at 11:54
3

Here is the Vim solution using Vim's Ex mode and the global command.

This is very similar to using sed, only that some special chars ('{', '}') need to be escaped.

:g/^.\{,3\}$/d

Using Vim's Very Magic Regex mode (\v), this escaping can be avoided.

:g/\v^.{,3}$/d

See also :help magic

Use of "\v" means that in the pattern after it all ASCII characters except
'0'-'9', 'a'-'z', 'A'-'Z' and '_' have a special meaning.  "very magic"

Also sometimes useful is to do the opposite with vglobal.

:v/\v^.{,3}$/d

would delete everything but lines till 3 chars.

1

to directly remove the lines you could:

sed -ri '/.{4}/!d' /path/to/file

Or BRE:

sed -i '/.\{4\}/!d' /path/to/file

If a line does not contain 4 or more characters it is deleted.

f=/path/to/file
cat <<GREP >"$f"
    $(grep -E ".{4}" "$f")
GREP

Doing the above in command-substitution subshell will ensure that grep gets a read descriptor on it before cat starts writing to it, but the <<HEREDOC will also ensure that the result remains streamed and does not cause argument length errors.

0
sed '/^.\?.\?.\?$/d' input.txt > output.txt
0

You can use grep:

If you count leading spaces in line length:

grep -e '[^\ ]\{4,\}' file

If you don't count leading spaces in line leangth:

grep -e '[^\]\{4,\}' file

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.