20

How can i delete a line if it is longer than e.g.: 2048 chars?

  • Do you insist on using sed? This is easy, for example in python. And no doubt even easier in perl. Though the question is not terribly well defined. Copy a file, removing all lines longer than 2048, or something else? – Faheem Mitha Mar 23 '11 at 18:21
21
sed '/^.\{2048\}./d' input.txt > output.txt
  • 3
    I get the error message sed: 1: "/^.\{2048\}..*/d": RE error: invalid repetition count(s) (Mac OS X) – wedi Oct 13 '14 at 15:47
  • 1
    @wedi you probably want to install the GNU version instead of the BSD version that ships with Mac. This is easy with brew – Freedom_Ben Jul 6 '16 at 0:00
6

Here's a solution which deletes lines that has 2049 or more characters:

sed -E '/.{2049}/d' <file.in >file.out

The expression /.{2049}/d will match any line that contains at least 2049 characters and deletes them from the input, producing only shorter line on the output.

With awk, printing lines of length 2048 or shorter:

awk 'length <= 2048' <file.in >file.out

Mimicking the sed solution literally with awk:

awk 'length >= 2049 { next } { print }' <file.in >file.out
  • 1
    I get the error message sed: 1: "/^.\{400,\}$/d": RE error: invalid repetition count(s) (Mac OS X) – wedi Oct 13 '14 at 15:47
  • 1
    @wedi Now updated and tested on macOS Mojave. – Kusalananda Nov 29 '18 at 23:20
2

Something like this should work in Python.

of = open("orig")
nf = open("new",'w')
for line in of:         
    if len(line) < 2048:
        nf.write(line)
of.close()
nf.close()
  • 1
    Personally, @Faheem, I prefer your answer. The reason why is that it was very easy for me to turn it around into 'delete all lines smaller than x'. I don't use Python all the time, but when I do I always feel I should learn it well. – ixtmixilix May 22 '11 at 18:18
  • @ixtmixilix: Yes, using a full featured language like Python is pretty flexible. Thanks for the comment. – Faheem Mitha May 24 '11 at 16:46
1
perl -lne "length < 2048 && print" infile > outfile
  • +1 The -l isn't needed, though. – Joseph R. Jan 29 '14 at 17:22
  • Does not work for me. Perl v5.16.2. Warning: Use of "length" without parentheses is ambiguous at -e line 1. Unterminated <> operator at -e line 1. – wedi Oct 13 '14 at 15:51
  • You may try length($_) > 2048 && print. length is a shortcut for length($_) anyway. – MaratC Nov 17 '14 at 12:10
0

The above answers do not work for me on Mac OS X 10.9.5.

The following code does work:

sed '/.\{2048\}/d'.

Although not asked, but provided for reference, the reverse can be achieved the following code:

sed '/.\{2048\}/!d'.

  • lol, but sed: 1: "/.\{2048\}/d": RE error: invalid repetition count(s) (Mac OS X, 10.10.4) – alex gray Jul 24 '15 at 13:29
  • Ah. I installed the GNU version instead of the BSD version that ships with Mac as @Freedom_Ben suggested above. But Kusalananda found the switch to enable extended regex. So you should go with his solution if you still have that problem. ;) – wedi Nov 30 '18 at 19:40
0

With gnu-sed, you may use the -r flag, to avoid typing the backslashes, and a comma, to define an open interval:

sed -r  "/.{2049,}/d" input.txt > output.txt

with:

  • x{2049} meaning exactly 2049 xs
  • x{2049,3072} meaning from 2049 to 3072 xs
  • x{2049,} meaning at least 2049 xs
  • x{,2049} meaning at most 2049 xs

For the intervals, to not match bigger patterns, you would need line anchors like

sed -r  "/^.{32,64}$/d" input.txt > output.txt 

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.