Сгенерировать файл .txt с определенным содержимым из недопустимого файла .json размером 3 ГБ

Если монтирование /lib делает недоступными такие важные библиотеки, как cp, cd, mount, umount, то

/bin/busybox umount /lib

размонтирует каталог. Библиотеки снова будут работать.

Thanks https://unix.stackexchange.com/users/182562/ipor-sircer !

1
24.03.2017, 22:42
2 ответа

Вы можете использовать команду grep для поиска нужных вам шаблонов, и sort для отсеивания дубликатов. Если ваш входной файл - input.json, а выходной - usernames.txt:

grep -P -o '(?<="username":")[^"]*' input.json | sort -u > usernames.txt

Разбираемся:

  • grep - это утилита командной строки для поиска регулярных выражений в файле. Регулярные выражения - это мощный способ описания фрагментов текста, которые вы хотите найти
  • -P указывает grep использовать "Perl-совместимые регулярные выражения". Обратите внимание, что на странице man для grep это описано как "очень экспериментальное"!
  • -o указывает grep выводить только совпадающий текст. По умолчанию grep обычно выводит всю строку, где найдено совпадение.
  • '(?<="имя пользователя":")[^"]*' - это само регулярное выражение:
    • Мы заключили его в одинарные кавычки '....', чтобы остановить командную строку от попыток интерпретировать что-либо в нем
    • (?<=...) - это то, что называется lookbehind assertion. Оно говорит, что мы хотим найти "username":" перед чем-то еще, но не включать это в вывод
    • [^"]* означает "как можно больше символов, которые не являются ". Его можно разбить еще раз:
    • [...] - это класс символов. Любой символ, который вы поместите между квадратными скобками, разрешен на данном этапе. Если только...
    • ^" Когда вы используете каретку ^ в качестве первого символа в классе символов, это означает не любой из следующих символов
    • * означает 0 или более из предыдущего элемента (который в данном случае является целым [^"]).

Передача лота через sort сортирует имена пользователей в алфавитном порядке, что с опцией -u означает "только уникальные элементы", т.е. никаких дубликатов.

Примечание: Все это предполагает, что шаблон, который мы подбираем, не может встретиться в другом месте файла (что кажется маловероятным), или что неполнота самого JSON не приведет к неудаче (что может быть, я не уверен, каким образом ваш файл неполноценен).

EDIT:. Поскольку grep регулярно жаловался, что строки слишком длинные, а sed -e 's/,/,\n/' почему-то тоже не работал, команда split была использована для разбиения файла на более управляемые куски.

2
27.01.2020, 23:34

Похоже, у вас очень длинные записи JSON, которые нарушают grep -P , вот альтернативное решение:

grep -o '"username":"[^"]*' users.json \
| cut -d '"' -f 4 \
| uniq \
| sort -u \
> usernames.txt

Здесь grep извлекает полные поля «имя пользователя: значение», cut извлекает значение, а uniq | sort -u делает имена пользователей уникальными.

uniq не требуется. С файлом размером 3 ГБ я ожидаю список из миллионов имен с множеством последовательных дубликатов. На первый взгляд бесполезный uniq | освобождает sort от части его работы и может ускорить его выполнение. Иначе не повредит.

-1
27.01.2020, 23:34

Теги

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