Использование AWK для разбиения частей одного файла на несколько файлов, но мне нужно дальнейшее направление

Я все еще новичок в этом типе задач, но я исчерпал свои ресурсы и поэтому протягиваю руку помощи.

У меня есть один файл, состоящий из объединенных файлов. Я могу использовать точную строку кода ниже, чтобы разбить файлы на части:

awk "/PATTERN/{x="F"++i;}{print > x;}" sourceFile

НО -

  1. Если возможно, я хотел бы указать каталог для выходных файлов - приведенный выше сценарий записывает выходные файлы в каталог «sourceFile», я бы хотел, чтобы эти файлы были сброшены в какой-то временный каталог.

  2. Было бы чрезвычайно полезно, если бы выходные файлы могли сохранять свое имя «sourceFile», возможно, со счетчиком в конце, сохраняя при этом тип файла .txt, то есть sourceFile1.txt, sourceFile2.txt и т. д.

Я попытался сохранить имя исходного файла, но безуспешно:

set F=sourceFile
awk "/PATTERN/{x="F"++i;}{print > x;}" sourceFile

Прошу прощения, если это элементарно, но это может сильно помочь в повседневных задачах, поэтому я надеялся, что кто-то может помочь. Заранее спасибо!


person Josh H    schedule 29.04.2013    source источник
comment
возможный дубликат разбитых файлов AWK на более мелкие файлы по шаблону   -  person mschilli    schedule 07.09.2013


Ответы (2)


awk может принимать переменные оболочки, если вы хотите установить каталог и имя файла:

D="/path/to/newfiles/"
F="sourceFile"

awk -v d="$D" -v f="$F" '/PATTERN/{x=d f (++i)}{print > x;}' sourceFile

теперь целевой каталог и имя файла являются динамическими, вы можете установить для них правильные значения перед вызовом awk.

но есть еще одна вещь, на которую следует обратить внимание. сколько PATTERN в вашем файле. если их слишком много, вы увидите сообщение об ошибке, например, «открыто слишком много файлов». в этом случае вы должны закрыть последний файл перед записью в новый.

person Kent    schedule 29.04.2013

Вы в значительной степени там просто добавляете префикс имени файла к каталогу и добавляете расширение файла, используя конкатенацию строк:

awk '/PATTERN/{file="tmp/"(FILENAME)(++i)".txt"}{print > file}' sourceFile

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

Демонстрация:

$ cat sourceFile 
PATTERN sf1
sf1
sf1
sf1
PATTERN sf2
sf2
sf2
PATTERN sf3
sf3
sf3

$ awk '/PATTERN/{file="tmp/"(FILENAME)(++i)".txt"}{print > file}' sourceFile

$ cat tmp/sourceFile1.txt
PATTERN sf1
sf1
sf1
sf1

$ cat tmp/sourceFile2.txt 
PATTERN sf2
sf2
sf2

$ cat tmp/sourceFile3.txt 
PATTERN sf3
sf3
sf3
person Chris Seymour    schedule 29.04.2013
comment
Спасибо, Судо. Я считаю, что ваше решение ближе всего к тому, что я ищу, но местоположение вывода все еще остается проблемой: awk /PATTERN/{file=my/tmp/dir(FILENAME)(++i)}{print › file } srcfile ›› Выдает эту ошибку: awk /PATTERN/{file=my/tmp/(FILENAME)(++i)}{print › file} srcFile awk: (FILENAME=sourceFile.txt FNR=1) фатальный: деление на нулевая попытка.... Мысли? - person Josh H; 30.04.2013
comment
На какой платформе вы работаете и какая у вас версия awk? - person Chris Seymour; 30.04.2013
comment
GNU Awk 3.1.6 Windows 7. Извините, если вы имели в виду что-то другое, когда ссылались на платформу. - person Josh H; 30.04.2013
comment
Разве вы не должны использовать имена путей в стиле Windows (т.е. обратную косую черту) или вы работаете под cygwin? - person Chris Seymour; 30.04.2013
comment
Я пробовал оба - либо я получаю синтаксическую ошибку: в каталоге C: \, либо ошибку деления на ноль. Я знаю, что это должно быть что-то простое, я просто скучаю по этому. - person Josh H; 30.04.2013
comment
Я придумал обходной путь и очень ценю вашу помощь, потому что вы решили мою проблему с именами файлов - это все равно было бы полезно и помогло бы мне в моем образовании, чтобы полностью решить проблему с выходным местоположением. - person Josh H; 30.04.2013
comment
@JoshH Я не знаком с нюансами awk в Windows, но вы пробовали использовать двойную обратную косую черту "my\\tmp\\dir" и C:\\directory\\ ? - person Chris Seymour; 30.04.2013
comment
Я еще не пробовал это - я не знал, что это будет иметь значение. Я попробую это и отчитаюсь - person Josh H; 30.04.2013