Есть файл вот с таким содержимым:
ОРГАНИЗАЦИЯ|
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
ОРГАНИЗАЦИЯ
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
ОРГАНИЗАЦИЯ
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
ОРГАНИЗАЦИЯ
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
ОРГАНИЗАЦИЯ
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
ОРГАНИЗАЦИЯ
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
НАЧИСЛЕНИЕ|
Таких строк может быть любое количество, как в меньшую, так и в большую сторону. После слов "ОРГАНИЗАЦИЯ" строка продолжается наименованием и реквизитами организации.
После слов "НАЧИСЛЕНИЕ" строка продалжается суммой начисления и пр. данными.
Разделитель |
Задача такая - с помощью awk найти слово "ОРГАНИЗАЦИЯ", скопировать содержимое этой строки и привязанные к ней строки "НАЧИСЛЕНИЕ".
Т.е. первую строку "ОРГАНИЗАЦИЯ" и две строки ниже со словом "НАЧИСЛЕНИЕ". Вывести эти 3 строки в отдельный файл.
Найти след. строки по такому же принципу и опять в отдельный файл.
По этому примеру должно быть 6 файлов и каждый со своей организацией и начислениями.
Пробовал так:
awk " /ОРГАНИЗАЦИЯ/{flag=1}flag; /ОРГАНИЗАЦИЯ/{flag=0} " E:\Мой файл.txt >> E:\Exit.txt
- выводятся строки только с этими словами, но не строки между ними.
awk " length($1) = 11 " FS="|" E:\Мой файл.txt >> E:\Exit.txt
- записывается все строки со словом ОРГАНИЗАЦИЯ
awk " length($1) >= 10 " FS="|" E:\Мой файл.txt >> E:\Exit.txt
Получаю все строки со словами ОРГАНИЗАЦИЯ и НАЧИСЛЕНИЕ
Извиняюсь за дурацкий вопрос. Знаний по awk нет, а задача есть.
Следующая команда awk будет искать по шаблону «ОРГАНИЗАЦИЯ» и выводить эту и следующие две строки целиком. Данные для обработки находятся в файле с именем test.txt. В awk можно организовать и вывод по отдельным файлам, но получится очень громоздко. Поскольку весь вывод awk нужно разбить на равные куски по 3 строки, с этим прекрасно справится split. В результате получается:
awk '/ОРГАНИЗАЦИЯ/{x=NR+2}(NR<=x){print}' test.txt | split -l 3
Поскольку весь вывод awk нужно разбить на равные куски по 3 строки, с этим прекрасно справится split.
Не совсем так. Необходимо узнать сколько строк между двумя словами ОРГАНИЗАЦИЯ и вывести все строки, которые находятся между ними
Вот решение на чистом awk. Тестовый файл test.txt:
awk -v y=0 -v mial=0 '/ОРГАНИЗАЦИЯ/{x=NR+2;z=""} (NR<=x){z=z$0"\r\n";y++} (y==3){print z>mial;y=0;mial++}' test.txt
Не совсем так. Необходимо узнать сколько строк между двумя словами ОРГАНИЗАЦИЯ и вывести все строки, которые находятся между ними
Тогда так:
awk -v y=0 '/ОРГАНИЗАЦИЯ/{if(x) print x>y; x=$0 ;y++} !/ОРГАНИЗАЦИЯ/{x=x"\r\n"$0} END {print x>y}' test.txt
<a href=" удаленная ссылка " target="true"> удаленная ссылка
Спасибо большое, ребят, но всё равно не работает
Продублируйте сообщение - до трёх сообщений нельзя вставлять ссылки...
На скриншоте не та команда, которая приведена здесь — по крайней мере, я не вижу в команде на скриншоте одинарных кавычек.
И ещё — к команде добавлено перенаправление вывода? Зачем?! В исходной команде уже есть перенаправление вывода в файлы… Видимо, вы не совсем её понимаете.
Вот скриншот:
На нём я захожу в каталог и проверяю, что никаких файлов, кроме исходного с данными, нет. Запускаю команду и затем в папке появляются 6 новых файлов. Я вывожу содержимое первых трёх файлов.
Вот команда для Windows:
awk.exe -v y=0 "/ОРГАНИЗАЦИЯ/{y++; print $0>y\".txt\";} !/ОРГАНИЗАЦИЯ/{print $0>y\".txt\"}" test.txt
Входные данные в файле test.txt. Тестировалась в cmd (а не в PowerShell). Ничего в команде менять не надо и редиректы делать не надо (они там есть!).
Скриншот:
Содержимое первых четырёх файлов:
P.S.
Для работы с Linux утилитами в Windows рекомендую освоить Cygwin — в этом случае будут работать все рецепты и все советы для Linux и отпадёт очень много головной боли.
Или выполнять подобные задачи в самом Linux.
Спасибо огромное-всё работает. Не могли бы вы посоветовать какую-нибудь литературу для изучения данного языка?
Подскажите, пожалуйста, как добавить в существующий файл строку с нужными мне данными?
Т.е. есть файл, например, с 6 строками и я хочу добавить сроку перед 1 строкой или добавить строку во все .txt файлы в определенной папке.
P.S. awk для виндовс.
Решение только для Linux. Если кому-то нужно для Windows, изучайте логику этого примера и делайте сами под Windows (работать с awk в Windows это как разговаривать на языке, когда запрещено использовать некоторые буквы — возникает главный вопрос, ЗАЧЕМ так мучится?).
Итак, следующий пример считывает все файлы из текущего каталога (*). Если нужно, чтобы считывал только файлы с определённым разрешением, то вместо звёздочки можно записать, например, так *.txt.
Для каждого обрабатываемого файла в самое начало добавляется строка "СТРОКА" — замените на нужную. Новые файлы сохраняются в эту же папку, с такими же именами, но перед именем добавляется префикс "new_" - при желании, его можно удалить или заменить на другой (в двух местах команды!).
Собственно команда:
awk -v 'OLD_FILENAME=""' '{if(OLD_FILENAME!=FILENAME) print "СТРОКА" > "new_"FILENAME; OLD_FILENAME=FILENAME} {print > "new_"FILENAME;}' *
Логика работы:
- при запуске awk инициализируется переменная OLD_FILENAME — которой в качестве значения присваивается пустая строка
- при обработке каждой строки, значение переменной OLD_FILENAME сравнивается со значением встроенной переменной FILENAME в которой (сюрприз!) содержится имя текущего файла. Если эти значения НЕ равны, то в файлы печатается строка "СТРОКА" И переменной OLD_FILENAME присваивается значение, которое содержит FILENAME.
- следующая часть {print > "new_"FILENAME;} просто печатает очередную строку в новый файл
- при последующих прохождениях (вторая строка, третья строка и т. д.) значения OLD_FILENAME и FILENAME будут одинаковыми. Вплоть до момента, пока обрабатываемый файл не сменится на новый. В этот момент OLD_FILENAME и FILENAME становятся не равны и в новый файл первой печатается строка "СТРОКА" и переменной OLD_FILENAME присваивается значение FILENAME
- всё продолжается, пока все строки во всех файлах не кончатся
Вот так для Windows (cmd, а не PowerShell):
awk.exe -v OLD_FILENAME="" "{if(OLD_FILENAME!=FILENAME) print \"СТРОКА\" > \"new_\"FILENAME; OLD_FILENAME=FILENAME} {print > \"new_\"FILENAME;}" *.txt
А что у вас там за секта «awk для Windows». Зачем вам это? Это какое-то домашнее задание что ли?
Нет, в организации компы только на Виндовс. Выдали задание и один человек подсказал, что подобное можно сделать на awk..с тех пор и мучаемся, пытаясь решить эту проблему не имея знаний ни в awk под Линукс и тем более под Windows. Лопатим интернет, но это не сильно помогает - мало информации, а под Виндовс и вовсе нет.