Изящный способ искать файлы UTF-8 с BOM?

Может быть немного не по теме, но это то, что у нас есть для List<T>, а не Stream<T>.

Сначала вам понадобится метод take util. Эти методы принимают первые n элементы:

static <T> List<T> take(List<T> l, int n) {
    if (n <= 0) {
        return newArrayList();
    } else {
        int takeTo = Math.min(Math.max(n, 0), l.size());
        return l.subList(0, takeTo);
    }
}

он работает только как scala.List.take

    assertEquals(newArrayList(1, 2, 3), take(newArrayList(1, 2, 3, 4, 5), 3));
    assertEquals(newArrayList(1, 2, 3), take(newArrayList(1, 2, 3), 5));

    assertEquals(newArrayList(), take(newArrayList(1, 2, 3), -1));
    assertEquals(newArrayList(), take(newArrayList(1, 2, 3), 0));

, теперь будет довольно просто написать метод takeWhile на основе на take

static <T> List<T> takeWhile(List<T> l, Predicate<T> p) {
    return l.stream().
            filter(p.negate()).findFirst(). // find first element when p is false
            map(l::indexOf).        // find the index of that element
            map(i -> take(l, i)).   // take up to the index
            orElse(l);  // return full list if p is true for all elements
}

он работает следующим образом:

    assertEquals(newArrayList(1, 2, 3), takeWhile(newArrayList(1, 2, 3, 4, 3, 2, 1), i -> i < 4));

эта реализация повторяет список частично в течение нескольких раз, но не добавляет add O(n^2) операций , Надеюсь, это приемлемо.

89
задан chills42 5 November 2008 в 13:54
поделиться

5 ответов

Как насчет этой простой команды, которая не только находит, но и очищает неприятные спецификации? :)

find . -type f -exec sed '1s/^\xEF\xBB\xBF//' -i {} \;

Мне нравится «найти»:)

Предупреждение Вышеупомянутое изменяет двоичные файлы, содержащие эти три символа.

.

Если вы хотите просто показать файлы спецификации, используйте этот:

grep -rl $'\xEF\xBB\xBF' .
160
ответ дан 24 November 2019 в 07:11
поделиться

При принятии некоторых ложных положительных сторон (в случае, если существуют нетекстовые файлы, или в маловероятном случае существует ZWNBSP посреди файла), можно использовать grep:

fgrep -rl `echo -ne '\xef\xbb\xbf'` .
7
ответ дан CesarB 5 November 2019 в 14:27
поделиться

Я использовал бы что-то как:

grep -orHbm1 "^`echo -ne '\xef\xbb\xbf'`" . | sed '/:0:/!d;s/:0:.*//'

, Который гарантирует, что BOM происходит, начиная на уровне первого байта файла.

5
ответ дан Marcus Griep 5 November 2019 в 14:27
поделиться
find -type f -print0 | xargs -0 grep -l `printf '^\xef\xbb\xbf'` | sed 's/^/found BOM in: /'
  • find -print0 помещает пустой \0 между каждым именем файла вместо того, чтобы использовать новые строки
  • xargs -0, ожидает, что пустой указатель отделился, аргументы вместо строки отделились
  • grep -l списки файлы, которые соответствуют regex
  • , regex ^\xeff\xbb\xbf не совершенно корректен, поскольку это будет соответствовать non-BOMed UTF-8 файлы, если у них будут пробелы нулевой ширины в начале строки
2
ответ дан Jonathan Wright 5 November 2019 в 14:27
поделиться
find . -type f -print0 | xargs -0r awk '
    /^\xEF\xBB\xBF/ {print FILENAME}
    {nextfile}'

Большинство приведенных выше решений проверяют больше, чем первая строка файла, даже если некоторые (например, решение Маркуса) затем фильтруют результаты. Это решение проверяет только первую строку каждого файла, поэтому оно должно быть немного быстрее.

13
ответ дан 24 November 2019 в 07:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: