Question: Recently had a LVM'd CentOS 6.5 install get accidentally cold-shutdown. On bootup, it says that the home partition need fscking:

```
/dev/mapper/vg_myserver-lv_home: Block bitmap for group 3072 is not in group.  (block 3335668205)

/dev/mapper/vg_myserver-lv_home: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.

```

...but I guess the root partition is OK, since it gives me a shell there. So we run `e2fsck -b 32768 /dev/mapper/vg_myserver/lv_home` and after saying Yes to various fixes, on Pass 5 it just prints endless numbers to the screen, very fast. Once in a while it will print them in neat columns, and if these are block numbers, after a couple hours we are still nowhere near the first 2% being done of our 1.2 TB LV.

I read that you can use `cleap_mmp` with `tune2fs`, but upon trying that, it doesn't accept cleap\_mmp nor list it among valid options.

My question is, how does everyone deal with a corrupt ext4 fs without weeks of downtime? Does everyone have this dilemma, or weeks of downtime vs rebuilding your server / lost data? If so why does anyone use or recommend the use of ext4? Is there some trick I'm missing that would **let me target the specific block/group it's complaining about**, so we can get on with it and mount the home fs again?

Answer: 
Okay...here's the clunky way for a five character string:

```
grep -P '^(.)(?!\1)(.)(?!\1|\2)(.)(?!\1|\2|\3)(.)(?!\1|\2|\3|\4).$'

```

Because you cannot put a back reference in a character class (e.g. `[^\1|\2]`), you must use a *negative look-ahead* -- `(?!foo)`. This is a PCRE feature so you need the `-P` switch.

The pattern for a 10 character string will be a lot longer, of course, but there is a shorter method using a variable length anything match ('.\*') in the lookahead:

```
grep -P '^(.)(?!.*\1)(.)(?!.*\2)(.)(?!.*\3)(.)(?!.*\4)(.)(?!.*\5).$'

```

---

After reading Stephane Chazelas's enlightening answer, I realized there is a similar simple pattern for this usable via grep's `-v` switch:

```
    (.).*\1

```

Since the check proceeds one character at a time, this will see if any given character is followed by zero or more characters (`.*`) and then a match for the back reference. `-v` inverts, printing only things which *don't* match this pattern. This makes the back references more useful since they can't be negated with a character class, and significantly:

```
grep -v '\(.\).*\1'

```

will work to identify a string of any length with unique characters whereas:

```
grep -P '(.)(?!.*\1)'

```

will not, since it will match whatever suffix with unique characters (e.g. `abcabc` matches because of `abc` at the end, and `aaaa` because of `a` at the end -- hence *any* string). This is a complication caused by lookarounds being zero-width (they do not consume anything).
A Perl solution:

```
perl -lne 'print if (!/(.)(?=$1)/g && /^\w{10}$/)' file

```

but it doesnt work with

```
perl -lne 'print if (!/(.)(?=\1)/g && /^\w{10}$/)' file

```

or

```
perl -lne 'print if ( /(.)(?!$1)/g && /^\w{10}$/)' file

```

tested with perl v5.14.2 and v5.18.2