Как разделить файл при помощи границ ключевого слова

Вы почти получили его действительно...

find . -type f -iname "*.java" -print0 | xargs -0 grep -v "something something"

Точка '.' говорит для запуска отсюда. (Ваш подразумевает его.. но никогда не принимайте).

- глупый поиск без учета регистра использования, на всякий случай (или просто ни в коем случае).
- print0 отправляет имена файлов в xargs с запаздыванием \x00 символ, который предотвращает проблемы с именами файлов, имеющими пробелы в них.

'-0' на xargs говорят для ожидания имен файлов, заканчивающихся \x00 вместо возвратов.

и Ваша команда grep...

В значительной степени получил его.


Править::

От Вашего обновления:

find . -type f -iname "*pb.java" -print0 | xargs -0 grep -iL "something"

должен помочь. (Добавленный-L из ответа @rush, хорошего задания)

Я получаю идею, что Вашему grep нужен или '-i' опция, или быть менее явным.

Попробуйте команду в частях... ЭТО производит имена файлов, которые кажутся надлежащими?

find . -type f -iname "*pb.java"

Если так, затем Ваша проблема вероятна, любой Ваш grep шаблон поиска не соответствует (орфографическая ошибка? это происходит!), или просто нет никаких соответствий.

Абсолютный худший случай:

grep -riL "something" *

сделает НАМНОГО больше работы, ищущей все, но должен дать Вам некоторый вывод.

14
25.05.2013, 17:33
5 ответов

Можно использовать awk для задания:

$ curl -O https://raw.githubusercontent.com/qtproject/qt-mobility\
/d7f10927176b8c3603efaaceb721b00af5e8605b/demos/qmlcontacts/contents/\
example.vcf

$ gawk ' /BEGIN:VCARD/ { close(fn); ++a; fn=sprintf("card_%02d.vcf", a); 
        print "Writing: ", fn } { print $0 > fn; } ' example.vcf
Writing:  card_01.vcf
Writing:  card_02.vcf
Writing:  card_03.vcf
Writing:  card_04.vcf
Writing:  card_05.vcf
Writing:  card_06.vcf
Writing:  card_07.vcf
Writing:  card_08.vcf
Writing:  card_09.vcf

$ cat card_0* > all.vcf
$ cmp example.vcf all.vcf
$ echo $?
0

Подробнее

awk строка работает как это: a счетчик, который увеличен на каждом BEGIN:VCARD строка и в то же время выходное имя файла создается с помощью sprintf (сохраненный в fn). Для каждой строки текущая строка ($0) добавляется в текущий файл (названный fn).

Последнее echo $? средства, что cmp было успешно, т.е. все единственные связанные файлы равны исходному примеру vcf пример.

Обратите внимание, что перенаправление вывода в awk работает по-другому, чем в оболочке. Это означает это с > fn awk сначала проверяет, открыт ли файл уже. Если это уже открыто затем awk, добавляет к нему. Если это не затем, это открывает и усекает его.

Из-за этой логики перенаправления мы должны явно закрыть неявно открытые файлы, так как иначе вызов поразил бы открытый предел файла в случаях, где входной файл содержит много записей.

11
27.01.2020, 19:50
csplit -f vcard input.txt -z '/END:VCARD/+1' '{*}'
11
27.01.2020, 19:50

Можно использовать этот сценарий, чтобы сделать задание. Это назвало split-vcf-file.

Использование в качестве примера

$ split_vcf.pl 

Error! Input VCF filename missing,  -i

Usage: perl split_vcf.pl -i input_file -o output_dir [OPTION]

    -v,         Verbosity levels, 1-3

Запускать скрипт:

mkdir vcf_files
split_vcf.pl  -i current.vcf -o vcf_files
4
27.01.2020, 19:50
  • 1
    split_vcf.pl является версией для Windows. поскольку Unix изменяет sub make_filename, который добавлял "\" в именах файлов. –  J Dan 08.11.2016, 00:39

Используя Параллель GNU можно сделать:

cat foo.vcf | parallel --pipe -N1 --recstart BEGIN:VCARD 'cat >{#}'

Или если можно опровергнуть http://oletange.blogspot.com/2013/10/useless-use-of-cat.html, можно использовать это вместо этого:

< foo.vcf parallel --pipe -N1 --recstart BEGIN:VCARD 'cat >{#}'

Посмотрите больше примеров: http://www.gnu.org/software/parallel/man.html

Посмотрите вводные видео: https://www.youtube.com/playlist? list=PL284C9FF2488BC6D1

Установка 10 секунд:

$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
   fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 3374ec53bacb199b245af2dda86df6c9
12345678 3374ec53 bacb199b 245af2dd a86df6c9
$ md5sum install.sh | grep 029a9ac06e8b5bc6052eac57b2c3c9ca
029a9ac0 6e8b5bc6 052eac57 b2c3c9ca
$ sha512sum install.sh | grep f517006d9897747bed8a4694b1acba1b
40f53af6 9e20dae5 713ba06c f517006d 9897747b ed8a4694 b1acba1b 1464beb4
60055629 3f2356f3 3e9c4e3c 76e3f3af a9db4b32 bd33322b 975696fc e6b23cfb
$ bash install.sh
4
27.01.2020, 19:50

Версия Гну csplit может установить расширение - ответ Ignacio, я думаю, является самым кратким, этому просто нужен тот последний бит тонкой настройки для получения расширения - использующий 'printf' формат:

csplit -f vcard -b %02d.vcard input.txt -z '/END:VCARD/+1' '{*}'

Вот соответствующий отрывок от гну csplit страница справочника:

   -b, --suffix-format=FORMAT
          use sprintf FORMAT instead of %02d
5
27.01.2020, 19:50

Теги

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