eXeL@B —› Оффтоп —› вопросы по shell. |
Посл.ответ | Сообщение |
|
Создано: 31 марта 2008 06:44 · Поправил: Small_S · Личное сообщение · #1 Привет всем. Суть проблемы в следующем. Идет сессия, по предмету "Операционные системы.", подвисает последняя контрольная. И вроде ничего мудреного, но что то недопру никак. Суть задания - создать скрипт в среде эмулятора системы UNIX- Cygwin, который бы в заданном каталоге у всех txt файлов создавал или менял(если она есть) первую строку файла на строку вводимую пользователем(желательно запуск с этими параметрами из командной строки). Пока упрощенный скрипт(последовательный ввод по приглашению) я создал только он почему то обрабатывает 2 файла и всё. Судя по пустому репорту обнаруженных файлов цикл отрабатывает полностью, а вот действия по вводу в каждый заголовок строки происходят не полностью(2раза).Скрипт имеет вид: echo Введите путь к каталогу в котором будут меняться заголовки файлов. read x; echo В каталоге обнаружены следующие файлы; find $x -type f -a -name '*.txt' > report.txt echo $( < report.txt); echo Введите новый заголовок этих файлов.; read y ostatok=5; while [ -n "$ostatok" ] do read imia ostatok < report.txt ostatok=$(sed report.txt -e {"1 d"}) echo $imia echo $y > $imia echo $ostatok > report.txt done Запускаю пока просто sh ren_contr(он без командных парам.). Действия понятны, но всё равно поясню. 1 -приглашение ввести каталог 2 -конвейер -->ввод пути каталога --> вывод сообщения о списке обнаруженных файлов --> сам поиск с записью репорт 3 -конвейер -->выводим из репорта список на экран --> приглашаем ввести заголовок --> сам ввод заголовка 4 -переменная для цикла(не ноль) 5 -начало цикла 6 -вводим из репорта в imia- первое слово в ostatok- второе слово(на данном этапе оно пустое- окончание строки так как путь с именем файла идёт как непрерывное слово и всё забирает переменная imia. 7 -присваиваем новое значение переменной ostatok после обрезки в sed-е первой строки. 8 -это просто для контроля выводим на экран 9 -наконец вносим заголовок на место в находящийся в переменной imia файл. 10 -а переменную ostatok c оставшимися файлами скидываем назад в репорт Цикл крутиться пока в репорте не исчезнет последняя запись. Вроде всё логично и выполняется,но... Может кто подскажет в чем дело, ну и другие варианты приветствуются, я пробовал тоже через sed заголовок писать в файлы в строке 9, но видимо косячу с синтаксисом, что то не получается. И ещё по ходу вопросы из которых главный нет ли отладчика под shell-ом чтобы посмотреть что происходит с переменными, методичка молчит, в гугле при описании скриптового языка не встречаю. Скрипты тоже искал в гугле, но на мою тему нет или не попалось. И вообще язык этот после асма и делфей, да даже после васика, смотрится как то убого, синтаксис-жесть. Текст и так может быть выражен,и так,и эдак, и вот вот так. В чём кайф не въеду. И вот эти задания в наших контрольных с работой с текстами ну так сочетаются с его возможностями( в sed поболее можно, но там ещё свой синтаксис сам чёрт ногу сломит пока их подружишь) просто вау. Если ещё учесть, что команды при выполнении скрипта можно брать только с двух методических пособий(а там кое чего нет), то картина станет полной. |
|
Создано: 31 марта 2008 09:32 · Личное сообщение · #2 1) команда echo $y > $imia заменит все содержимое, а не только первую строку 2) конструкция ostatok=$(sed report.txt -e {"1 d"}) приводит к тому, что убираются все символы конца строки и при втором исполнении в report.txt ничего не остается 3) для отладки можно использовать какой-то ключ при вызове sh - будет выдаваться протокол выполнения , либо просто выдавать на консоль содержимое переменных и файлов, чтобы убедится, что все работает так как ты задумал. Именно так я и определил, что записывется в переменную ostatok. |
|
Создано: 31 марта 2008 17:21 · Личное сообщение · #3 tundra37 большое человеческое спс. А то я уже в затуп от перенапряжения вхожу, вот и не сообразил как бы переменную глянуть. Однако теперь другой затык -сразу за структурой ostatok=$(sed report.txt -e {"1 d"}) пытаюсь восстановить возврат каретки(или как больше нравиться концы строк), делаю так как увидел на одном сайте там пример chrish@dhcp3 [345]$ echo -e 'hello\tthere' hello there chrish@dhcp3 [346]$ echo -e 'hello\tthere' | sed -e 's/[[:space:]]/, /' hello, there Моя конструкция которую принимает мой sed выглядит так: sed report.txt -e 's\[[:space:]]\[[:\r:]]\g' Двойной слеш там для экранирования как у меня для седа в методичках пишут. Млинн, спейс этот хренов sed махом меняет на всё что угодно только не на возврат каретки, с любым количеством скобок или с экранированием или без. Ему фиолетово,- команда s, которая исправно меняла всё чо хочешь сразу становится седу незнакомой(типа неизвестная операция 's'). Уж каким раком, боком я это \r или \015 или \x00D или даже Enter(хрен их придурков-разработчиков этого чуда-юда знает) не ставил. Всё без толку. Жена предлагает новопассит, но это не выход. Кто нибудь знает как возврат каретки символом в херовом sed-е задаётся? И ещё есть ли способ в shell-е как в делфях или нормальных скриптовых языках(типа олидбгскрипте) асм-вставки вставлять? Я заранее прошу прощения за весьма агрессивный пост у модераторов, но просто уже колотит от мысли, что за два дня хелоу ворлд не могу в пять шесть txt-шек написать программно. |
|
Создано: 01 апреля 2008 18:19 · Поправил: [HEX] · Личное сообщение · #4 |
|
Создано: 01 апреля 2008 21:57 · Личное сообщение · #5 [HEX] спс. завтра буду пробовать, уже сил нет $1-это так понимаю то где у меня найденные файлы были(report.txt) после find-а. Походу там с этой кареткой какой то цирк. Думал это sed из-за мудрёного синтаксиса-экранирования не всасывает, но вот попробовал tr [[:space:]] [[:\r:]] < $ostatok так тоже нивкакую теперь уже шеловая команда tr пробел видит а возврат каретки нет и как в седе меняет пробел на что хочеш только не на каретку. Тоже и экранировать по всякому пробовал, и так, и эдак, всякие слешики, кавычечки, скобочки, метасимволы ему полный фиолет, не, мягко выразился,- ультрафиолет. Всё это чудо, слышал как то, на си писалось тем более непонятно чего оно \r не всасывает(этож вроде сишное обозначение изначально) Не, помимо выполнения контрольной жутко интересно зачем так набаламутили с синтаксисом разработчики этож мешает кодингу. И команды тоже тяп ляп- она должна отрезать строку по указанному номеру, так строку режет и ещё удаляет каретку какого то(ну это хоть ленью можно обьяснить). А вот синтаксические изыски садо-мазо какое то. Или я в какойто запредельный, недоступный простым смертным кайф не въеду. |
|
Создано: 05 апреля 2008 10:07 · Личное сообщение · #6 Привет всем. Наконец прикончил задание. Млин пришлось ещё пару дней убить. В скрипт пришлось вносить второй цикл чтобы справиться с багом по удалению возврата каретки. С тем, что дал [HEX] разобрался, но уточнив у препода не стал туда вносить и мучиться совмещать(так как это чтобы строки старые не терялись, а смещались в конец под новый заголовок). Вот скрипт с внесением пути каталога и добавляемого заголовка из командной строки. Запускается стандартно: sh script2 <каталог где будем менять> <заголовок который вносим> Скрипт выглядит так(немного меняю для лучшего понимания): echo Введённый путь к каталогу в котором будут переименовываться файлы. x=$1; echo $x echo В каталоге обнаружены следующие файлы find $x -type f -a -name '*.txt' > report echo $( < report ) echo Введённый новый заголовок этих файлов.; y=$2; echo $y; ostatok=5 while [ -n "$ostatok" ] do read imia ostatok < report echo $ostatok; echo $ostatok > report2 ostatok=$(sed report -e {"1 d"}) echo $ostatok > report echo $y > $imia done ostatok2=5; while [ -n "$ostatok2" ] do read imia2 ostatok2 < report2 echo $ostatok2 echo $ostatok2 > report2 echo $y > $imia2 done Итак построчно выполняются действия: 1. Выводится надпись – сообщение о каталоге который ввели из командной строки. 2. Конвейер присваивает переменной x значение строки каталога и выводит его на экран. 3. Выводится надпись об списке обнаруженных файлов txt. 4. Осуществляется поиск файлов txt и помещение их списка в файл report. 5. Выводим список из файла report на экран. 6. Выводится сообщение о введённом в командной строке заголовке, переменной y присваивается значение из командной строки, это значение выводится на экран. 7. Переменная ostatok делается не равной нулю(на ней будет основан цикл). 8. Сообщаем циклу условие на работу – работаем пока ostatok не ноль. 9. Начало цикла. 10. Читаем из файла репорт в imia –первое слово(там путь первого файла), а в ostatok всё остальное. 11. Выводим значение остатка на экран(я оставил для наглядности эту отладочную информацию) . Далее скидываем ostatok в report2 так как сед ведёт себя на следующей команде неадекватно и при втором прогоне в переменной ostatok ничего не будет, а вся оставшаяся строка не имея символов возврата каретки уйдёт в imia. 12. Присваиваем переменной ostatok значение из файла report вырезав оттуда первую строку(предварительно sed-ом). 13. Скидываем новое содержимое из переменной ostatok назад в файл report. 14. Пишем требуемый заголовок в файл(имя и путь которого в переменной imia). 15. Коней цикла. 16. Инициализируем переменную ostatok2(делаем её не равной нулю) для второго цикла. Он нужен для того чтобы обойти баг с удалением символа возврата каретки,- иначе заголовок будет снесён в два первых по алфавиту файла. 17. Задаем условие работы второго цикла, он будет работать пока не равна нулю переменная ostatok2. 18. Начало цикла. 19. Вносим в переменную imia2 путь и имя файла в виде первого слова, а в переменную ostatok2 остальное из сохранённого ранее report2. 20. Оставил отладочный вывод значения ostatok2 на экран. 21. Пишем то, что осталось в ostatok2 назад в report2. 22. Наконец записываем по находящемуся в переменой imia2 адресу файл необходимый заголовок. 23. конец второго цикла. Но в этом скрипте есть еще серьезный недостаток,- из командной строки можно внести в заголовок только 1 слово на английском. Ниже первый вариант скрипта в режиме диалога с пользователем. Его запускаем без параметров типа так sh script1. echo Введите путь к каталогу в котором будут переименовываться файлы. read x; echo В каталоге обнаружены следующие файлы; find $x -type f -a -name '*.txt' > report echo $( < report ); echo Введите новый заголовок этих файлов.; read y ostatok=5; while [ -n "$ostatok" ] do read imia ostatok < report; echo $ostatok; echo $ostatok > report2; ostatok=$(sed report -e {"1 d"}) echo $ostatok > report echo $y > $imia done; ostatok2=5; while [ -n "$ostatok2" ] do read imia2 ostatok2 < report2; echo $ostatok2; echo $ostatok2 > report2; echo $y > $imia2 done В данном варианте можно вносить хоть предложение на русском или английском. Уф с этим предметом всё. Всем спасибо, но закрывать топик не буду. Может ещё у кого вопросы возникнут по shell и всем миром можно будет их решить. |
eXeL@B —› Оффтоп —› вопросы по shell. |