2

I have several huge .txt files and I need to remove a line if it is exactly 9 characters long. No more no less.

Is there a way to do this using awk / sed?

Pierre.Vriens
  • 1,088
  • 21
  • 13
  • 16
Ehatre
  • 23
  • 2
  • [How to remove lines shorter than XY?](http://unix.stackexchange.com/q/123243) and [How to delete line if longer than XY?](http://unix.stackexchange.com/q/9981)... – don_crissti Nov 27 '16 at 19:45
  • I saw those, but I need it to be exactly x length, not shorter than or longer than. – Ehatre Nov 27 '16 at 19:49
  • The solutions there require minor modifications to do what you want... I mean even someone who is not familiar with `sed`/`awk` should be able to change those commands to remove lines of a certain length. – don_crissti Nov 27 '16 at 19:54
  • Here's another one: [How to “grep” for line length *not* in a given range?](http://unix.stackexchange.com/q/249224) – don_crissti Nov 27 '16 at 20:15

5 Answers5

5

With GNU sed's extended regexes:

for file in ./*.txt; do
    sed -i -r '/^.{9}$/d' "${file}"
done

(Use -E instead of -r on FreeBSD/macOS (-E will also work in recent versions of GNU sed) and -i '' instead of -i)

As pointed out by don_crissti, with GNU sed you don't need the loop:

sed -s -i -r '/^.{9}$/d' ./*.txt
Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
4

With awk:

for f in ./*.txt; do
    awk 'length($0) != 9' "$f" >"destdir/$f"
done

With sed:

for f in ./*.txt; do
    sed '/^.\{9\}$/d' "$f" >"destdir/$f"
done

With grep:

for f in ./*.txt; do
    egrep -vx '.{9}' "$f" >"destdir/$f"
done
Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
Satō Katsura
  • 13,138
  • 2
  • 31
  • 48
  • Note that `\{` was added to `grep` before `{` was added to `egrep`. Some `egrep` implementations (like Solaris `/bin/egrep`) still don't support it (as that would break backward compatibility while the introduction of `\{` in BRE didn't break backward compatibility). The modern and standard equivalent of `egrep` is `grep -E` (on Solaris, you need `/usr/xpg4/bin/grep` or `command -p grep`). – Stéphane Chazelas Dec 07 '16 at 21:37
1

This may work:

grep -vE '^.{9}$' filename > new_filename

Switch the 9 to whatever characters needed.

       -v, --invert-match
          Invert the sense of matching, to select non-matching lines.
       -E, --extended-regexp
          Interpret PATTERN as an extended regular  expression  (ERE,  see
          below).

. means any character, {9} means match this pattern 9 times. ^ means start of line and $ means end of line.

Miati
  • 3,080
  • 4
  • 19
  • 24
1
awk length!=9 < in > out
Kaz
  • 7,676
  • 1
  • 25
  • 46
0
for i in *.txt
do
  egrep -v '^.........$' <"$i" >destdir/"$i"
done

Or, if you insist on using sed rather than egrep:

for i in *.txt
do
  sed '^.........$/d' <"$i" >destdir/"$i"
done

To remove lines that are 235 characters long:

X=""
for i in `seq 1 235`
do
  X="$X."
done

for i in *.txt
do
  egrep -v '^'"$X"'$' <"$i" >destdir/"$i"
done

Simplicity itself!

DepressedDaniel
  • 4,169
  • 12
  • 15