43

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

6 Answers 6

61

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
1
  • 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, 2018 at 14:50
11

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
  • 7
    Oh that grep .... is so elegant!
    – grofte
    May 15, 2019 at 11:54
7

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
  • Thanks. saved my day.
    – Michael S
    Mar 20, 2022 at 20:06
1

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
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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .