Редактирование файла в bash (Debian lenny)

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

Аватара пользователя
amorphius
Сообщения: 353
ОС: Ubuntu

Редактирование файла в bash

Сообщение amorphius »

Задача простая вроде: сделать элементарные изменения в текстовом файле, но только с помощью баша. Не знаю какие функции использовать, я то понимаю что чтения/записи, но не знаю как они называются и их форматы. Поиск по форуму привел на одну темку, где делалось это с помощью функций read и printf (кто бы мог подумать:)), но как то больно непонятно было написано, решил почитать маны, да не тут то было, ман показал мне функции С, а не команды баша.
К примеру есть текстовый файл:

Код: Выделить всё

132 some text
133 and again..
134 and again...
140 some text which had to be edited
145 something else
146 ok, enough...
147 I say enough:)

Как изменить какую нить строчку, например под номером 140, текстом, который введет пользователь с клавиатуры?
Спасибо сказали:
allez
Сообщения: 2223
Статус: Не очень злой админ :-)
ОС: SuSE, CentOS, FreeBSD, Windows

Re: Редактирование файла в bash

Сообщение allez »

Вам может помочь man sed. Или его нельзя использовать по условиям задачи? Если нельзя, то читайте Advanced Bash-scripting guide, в частности раздел 9.2. Работа со строками.
Спасибо сказали:
Аватара пользователя
amorphius
Сообщения: 353
ОС: Ubuntu

Re: Редактирование файла в bash

Сообщение amorphius »

Спасибо, почитаю. В задаче главное, чтобы я научился сам писать скрипты, умеющие обрабатывать текстовые файлы:)
Желательно, чтоб не зависило от дистрибутива
Спасибо сказали:
allez
Сообщения: 2223
Статус: Не очень злой админ :-)
ОС: SuSE, CentOS, FreeBSD, Windows

Re: Редактирование файла в bash

Сообщение allez »

Функцональность sed, как правило, одинакова во всех более-менее близких друг другу по дате выпуска дистрибутивах, поскольку в их состав чаще всего входят одинаковые версии sed. Впрочем, за последний десяток лет я сталкивался с отличиями в работе только лишь его GNU- и не GNU-версий. То же самое можно сказать и про bash, awk, perl...

P. S. Кстати, на всякий случай: я малость подредактировал свое предыдущее сообщение.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Редактирование файла в bash

Сообщение drBatty »

amorphius писал(а):
30.10.2009 17:50
ман показал мне функции С, а не команды баша.

попробуйте

Код: Выделить всё

 man 1 printf
help read
info sed

кстати, printf и read совсем для других целей обычно используют, используйте sed.


allez писал(а):
30.10.2009 18:02
Функцональность sed, как правило, одинакова во всех более-менее близких друг другу по дате выпуска дистрибутивах, поскольку в их состав чаще всего входят одинаковые версии sed.

вы не поверите! но в венде есть точно такая-же sed :)

PS: начните отсюда: http://sed.sourceforge.net/
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
amorphius
Сообщения: 353
ОС: Ubuntu

Re: Редактирование файла в bash

Сообщение amorphius »

Не, перл нельзя использовать, как никак совсем другой язык программирования, а вот sed, awk по-моему то, что надо. Результаты потом сообщу
Спасибо сказали:
allez
Сообщения: 2223
Статус: Не очень злой админ :-)
ОС: SuSE, CentOS, FreeBSD, Windows

Re: Редактирование файла в bash

Сообщение allez »

drBatty писал(а):
30.10.2009 18:07
вы не поверите! но в венде есть точно такая-же sed
Охотно поверю, особенно если вы покажете, где в "Установке компонентов Windows" нужно поставить "галку" для его установки. ;)
А то у меня он что-то не запускается. :)

cmd

C:\>sed "sed" не является внутренней или внешней командой, исполняемой программой или пакетным файлом.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Редактирование файла в bash

Сообщение drBatty »

allez писал(а):
30.10.2009 18:10
Охотно поверю, особенно если вы покажете, где в "Установке компонентов Windows" нужно поставить "галку" для его установки. ;)
А то у меня он что-то не запускается. :)

я ссылку вам дал.
в САМОЙ винде конечно ничего нет, даже текстового редактора или компилятора.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
amorphius
Сообщения: 353
ОС: Ubuntu

Re: Редактирование файла в bash

Сообщение amorphius »

sed работает почти как мне и надо, только вот вопросик какой: почему вот такой код...

Код: Выделить всё

filename="~/somefile"
sed "s/a/u" "$filename" > $filename

...который по идее меняет все буквы a на u в файле, но файл после этого становится пустым?
Попробовал поставить >> - заработало. Почему? Насколько помню > означает запись в новый файл, а >> - добавление
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: Редактирование файла в bash

Сообщение sash-kan »

sed -i
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
allez
Сообщения: 2223
Статус: Не очень злой админ :-)
ОС: SuSE, CentOS, FreeBSD, Windows

Re: Редактирование файла в bash

Сообщение allez »

drBatty писал(а):
30.10.2009 18:07
вы не поверите! но в венде есть точно такая-же sed :)

drBatty писал(а):
30.10.2009 21:37
я ссылку вам дал.

Вот любопытно, откуда у вас взялась такая непоколебимая уверенность в моем неведении о существовании порта sed для Windows? :)
Я использую его там с начала текущего века в составе UnxUtils и вполне доволен. :)

P. S. Вы меня случаем ни с кем не попутали? ;)
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Редактирование файла в bash

Сообщение drBatty »

allez писал(а):
30.10.2009 18:10
А то у меня он что-то не запускается. :)

allez писал(а):
31.10.2009 06:30
Вот любопытно, откуда у вас взялась такая непоколебимая уверенность в моем неведении

дык, если вы, по собственному признанию, не можете запустить, то я вам рассказываю - как это сделать. ;)
а если вы уже почти 10 лет уже запускаете, откуда такие вопросы?
allez писал(а):
31.10.2009 06:30
P. S. Вы меня случаем ни с кем не попутали? ;)

я, честно говоря, сам только недавно узнал о том, что sed есть в windows. Т.е. я думал, что "наверное должна быть", но вообще-то этот вопрос меня очень мало волновал. Кроме того, разные версии sed практически ничем не отличаются, за исключением z и v мне не вспомнить никаких отличий новой версии от той, что была лет 5 назад (5 лет - целая эпоха ИМХО). сама sed развивается уже лет 30 с лишнем, потому навряд-ли там появятся какие-то новые фичи и т.д...
sash-kan писал(а):
30.10.2009 22:54
sed -i

ага. а лучше
sed -i.SUFFIX
что-бы сохранить старый файл с расширением SUFFIX.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
allez
Сообщения: 2223
Статус: Не очень злой админ :-)
ОС: SuSE, CentOS, FreeBSD, Windows

Re: Редактирование файла в bash

Сообщение allez »

drBatty писал(а):
31.10.2009 16:25
дык, если вы, по собственному признанию, не можете запустить, то я вам рассказываю - как это сделать. ;)
а если вы уже почти 10 лет уже запускаете, откуда такие вопросы?
Э-э, минуточку, вы хронологию-то соблюдайте. :)

drBatty писал(а):
30.10.2009 18:07
вы не поверите! но в венде есть точно такая-же sed :)
allez писал(а):
30.10.2009 18:10
А то у меня он что-то не запускается. :)

Сначала вы заявили, что sed в Винде есть и только после этого я, не совсем верно вас поняв (отчасти тому причиной мой грех, отчасти - ваша формулировка, допускающая неоднозначное толкование ;)), попытался запустить его на "голой" системе со вполне очевидным результатом. :)

Ну а если серьезно, то мы с вами неплохо подурачились тут на пару. :) Можно, наверное, и наступить на горло собственной песне, пока модераторы не сделали это за нас. ;)
Спасибо сказали:
Аватара пользователя
Frank
Сообщения: 1059
ОС: Ubuntu, Debian

Re: Редактирование файла в bash

Сообщение Frank »

amorphius писал(а):
30.10.2009 22:07
sed работает почти как мне и надо, только вот вопросик какой: почему вот такой код...

Код: Выделить всё

filename="~/somefile"
sed "s/a/u" "$filename" > $filename

...который по идее меняет все буквы a на u в файле, но файл после этого становится пустым?
Попробовал поставить >> - заработало. Почему? Насколько помню > означает запись в новый файл, а >> - добавление

Потому что конвейнер выполняется справа налево. Т.е. сперва будет затёрт файл, и затем из него пойдёт считывание. Чтобы не мучиться с промежуточным файлов, см. уже подсказанную опцию -i
Изображение
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Редактирование файла в bash

Сообщение drBatty »

allez писал(а):
31.10.2009 17:04
попытался запустить его на "голой" системе со вполне очевидным результатом. :)

ИМХО на голой венде вообще ничего не работает. т.ч. оставим эту тему, для вендовых форумов :)
allez писал(а):
31.10.2009 17:04
Можно, наверное, и наступить на горло собственной песне, пока модераторы не сделали это за нас. ;)

мда... верно.
amorphius писал(а):
30.10.2009 22:07
Попробовал поставить >> - заработало.

тут - да. но в общем случае опасно дописывать в файл, при этом его и читая.
  • >
    Этот оператор создаёт новый файл или усекает существующий до нуля (если есть).
  • >>
    Этот - открывает файл на добавление. Т.е. информация в файле вроде-бы сохраняется. Однако, не всегда возможно гарантировать непротиворечивое чтение и одновременную запись в один и тот-же файл.

Что-бы не наступить на эти грабли - используйте временный файл, например

Код: Выделить всё

sed '' file1.txt > temp.txt
mv temp.txt file1.txt

Именно так и работает sed с ключом -i.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
amorphius
Сообщения: 353
ОС: Ubuntu

Re: Редактирование файла в bash

Сообщение amorphius »

Frank писал(а):
31.10.2009 21:47
Потому что конвейнер выполняется справа налево. Т.е. сперва будет затёрт файл, и затем из него пойдёт считывание.

хм.. а почему сперва будет затерт файл?

drBatty писал(а):
01.11.2009 01:28
и грабли - используйте временный файл, например

Код: Выделить всё

sed '' file1.txt > temp.txt
mv temp.txt file1.txt

Именно так и работает sed с ключом -i.

не, нельзя временный файл, потому что работаем в директории,где очень ущемлены в правах. я понимаю, конечно, что можно создать временный файл в своем домашнем каталоге, но хочется как то попроще сделать
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Редактирование файла в bash

Сообщение drBatty »

amorphius писал(а):
01.11.2009 01:32
хм.. а почему сперва будет затерт файл?

оператор cat X > Y
сначала открывает файл X на чтение,
потом усекает и открывает Y на запись,
а уж потом читает X и пишет прочитанное в Y.

А вы думали, что сначала прочитается X? Ха! а если X размером 500Гб? :)

amorphius писал(а):
01.11.2009 01:32
не, нельзя временный файл, потому что работаем в директории,где очень ущемлены в правах. я понимаю, конечно, что можно создать временный файл в своем домашнем каталоге, но хочется как то попроще сделать

хочеться-не хочется, а sed так БУДЕТ делать.
Совет: делайте временный в /tmp или в /var/tmp.
amorphius писал(а):
01.11.2009 01:32
но хочется как то попроще сделать

часто простота только кажущаяся :(
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
amorphius
Сообщения: 353
ОС: Ubuntu

Re: Редактирование файла в bash

Сообщение amorphius »

drBatty писал(а):
01.11.2009 01:35
оператор cat X > Y
сначала открывает файл X на чтение,
потом усекает и открывает Y на запись,
а уж потом читает X и пишет прочитанное в Y.

ну хорошо, а как тогда объяснить, что...

Код: Выделить всё

sed "s/a/u" "$filename" >> $filename

...работает как мне и надо? По логике должны открыться файлы на чтение, читается содержимое файла, изменяется в соответствии с шаблоном, а потом добавляется в конец, итого в файле "старая" версия + "новая"
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5404
ОС: Gentoo

Re: Редактирование файла в bash

Сообщение /dev/random »

amorphius писал(а):
01.11.2009 02:37
ну хорошо, а как тогда объяснить, что...

Код: Выделить всё

sed "s/a/u" "$filename" >> $filename

...работает как мне и надо? По логике должны открыться файлы на чтение, читается содержимое файла, изменяется в соответствии с шаблоном, а потом добавляется в конец, итого в файле "старая" версия + "новая"

Буферизация. GNU Sed, если выводит не на терминал, то делает это большими порциями. Сделайте файл покрупнее, и перестанет работать. Может, даже будет писать вечно.
Спасибо сказали:
Аватара пользователя
amorphius
Сообщения: 353
ОС: Ubuntu

Re: Редактирование файла в bash

Сообщение amorphius »

отличная вещь awk+sed, но вот проблемка еще появилась очень странная:
не получается создать временный файл

Код: Выделить всё

tmp_file="~/tmp$$"
echo $sometext > $tmp_file

...пишет ошибку ./calendar.sh: line 4: ~/tmp4916: Nie ma takiego pliku ani katalogu
Ну по русски это нету файла. Естественно нету, потому что я его создаю...
Пробовал уже и touch $tmp_file; echo $sometext >> $tmp_file (а вдруг:)) - не помогает
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5404
ОС: Gentoo

Re: Редактирование файла в bash

Сообщение /dev/random »

Ну сказано же было: не мучайтесь, используйте sed -i, всё будет сделано автоматически.
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: Редактирование файла в bash

Сообщение diesel »

amorphius писал(а):
02.11.2009 19:48
отличная вещь awk+sed, но вот проблемка еще появилась очень странная:
не получается создать временный файл

Код: Выделить всё

tmp_file="~/tmp$$"
echo $sometext > $tmp_file

...пишет ошибку ./calendar.sh: line 4: ~/tmp4916: Nie ma takiego pliku ani katalogu
Ну по русски это нету файла. Естественно нету, потому что я его создаю...
Пробовал уже и touch $tmp_file; echo $sometext >> $tmp_file (а вдруг:)) - не помогает

Код: Выделить всё

tmp_file="~/tmp$$"

вот тут без кавычек
Спасибо сказали:
Аватара пользователя
amorphius
Сообщения: 353
ОС: Ubuntu

Re: Редактирование файла в bash

Сообщение amorphius »

дело в том, что имеется доступ только к одному файлу в каталоге, и вот такая команда например

Код: Выделить всё

sed -i "s/a/u/g" "$filename"

вызывает ошибку не могу создать временный файл /home/user//sed2yzst7
Спасибо сказали:
Аватара пользователя
diesel
Бывший модератор
Сообщения: 5989
ОС: OS X, openSuSE, ROSA, Debian

Re: Редактирование файла в bash

Сообщение diesel »

ЗЫ: или лучше tmp_file="$HOME/tmp$$"
Спасибо сказали:
Аватара пользователя
amorphius
Сообщения: 353
ОС: Ubuntu

Re: Редактирование файла в bash

Сообщение amorphius »

diesel писал(а):
02.11.2009 19:58
вот тут без кавычек

спасибо, заработало просто когда кавычки убрал
Спасибо сказали:
Аватара пользователя
amorphius
Сообщения: 353
ОС: Ubuntu

Re: Редактирование файла в bash

Сообщение amorphius »

опять проблемка, гугл молчит, так что к нему не посылать:)
такой вот код

Код: Выделить всё

founded=`awk "/^$date(.*)$/ { print; }" $filename`

вызывает ошибку если "плохие" символы имеются в $datе. Как правильно экранировать в данном случае?
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: Редактирование файла в bash

Сообщение sash-kan »

amorphius писал(а):
04.11.2009 21:33
опять проблемка, гугл молчит, так что к нему не посылать:)
такой вот код

Код: Выделить всё

founded=`awk "/^$date(.*)$/ { print; }" $filename`

вызывает ошибку если "плохие" символы имеются в $datе. Как правильно экранировать в данном случае?
а что вам, собственно, нужно? выдать строки, содержащие (в частности) то, что находится в переменной $date?
$ grep "^$date" "$filename"
или ещё и содержимое $date надо из этих строчек убрать?
$ grep "^$date" "$filename" | sed "s%^$date%%"
если в $date могут попасться символы «%», замените их на что-нибудь другое, явно там не встречающееся:
$ grep "^$date" "$filename" | sed "s|^$date||"
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали: