Форум русскоязычного сообщества Ubuntu


Получить помощь и пообщаться с другими пользователями Ubuntu можно
на irc канале #ubuntu-ru в сети Freenode
и в Jabber конференции ubuntu@conference.jabber.ru

Автор Тема: простой вопрос по bash  (Прочитано 2749 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
Re: простой вопрос по bash
« Ответ #15 : 17 Декабря 2016, 23:59:13 »
Вот если немного переделать:
Код: (bash) [Выделить]
for i in {1..50} ; do echo $i ; cp file.bkp file && sync && cat file | grep PATTERN | tee file > /dev/null ; [ -s file ] || break ; doneСрабатывает у меня по разному: от 1 до 3 циклов.

С моим вариантом:
Код: (bash) [Выделить]
for i in {1..50} ; do echo $i ; cp file.bkp file ; grep PATTERN file | (sleep 0.1 ; tee file >/dev/null); [ -s file ] || break ; done- Все 50.


Пользователь добавил сообщение 18 Декабря 2016, 00:17:20:
Цитировать
файлопомойка с торентами на древнем компе
У меня почти тоже самое.
« Последнее редактирование: 18 Декабря 2016, 00:44:45 от renzrv »

Оффлайн ALiEN

  • Администратор
  • Старожил
  • *
  • Сообщений: 6690
  • 20% Cooler
    • Просмотр профиля
Re: простой вопрос по bash
« Ответ #16 : 18 Декабря 2016, 00:42:44 »
Интересное дело происходит))

renzrv, первый вариант у меня все 50 отрабатывает, поставил 500 - на 71 запнулся, так что точно не вариант.
во втором варианте - 50 и 500 отработал. Так что задержка для tee всё-таки нужна.

Чем больше файл - тем больше задержка. В итоге, наверное, проще использовать промежуточный файл.

« Последнее редактирование: 18 Декабря 2016, 00:58:49 от ALiEN175 »
🖥 AsRock B550M Pro4 :: AMD Ryzen 5 3600 :: 16 GB DDR4 :: AMD Radeon RX 6600 :: XFCE
💻 ACER 5750G :: Intel Core i5-2450M :: 6 GB DDR3 :: GeForce GT 630M :: XFCE

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
Re: простой вопрос по bash
« Ответ #17 : 18 Декабря 2016, 01:19:09 »
Цитировать
Интересное дело происходит))
Наверно это из-за разных параметров памяти, ядра.
Вместо tee file >/dev/null можно использовать и cat.
Вобщем в итоге схема такая:
Код: (bash) [Выделить]
command1 file | command2 ... | (sleep 0.1 ; cat > file)
Цитировать
Чем больше файл - тем больше задержка. В итоге, наверное, проще использовать промежуточный файл.
Похоже если в левой части команда не успеет открыть и прочитать ВЕСЬ файл за время задержки, то файл будет пустым или будут не все данные:
Код: (bash) [Выделить]
( sleep 0.3 ; grep PATTERN file ) | ( sleep 0.1 ; cat > file )
« Последнее редактирование: 18 Декабря 2016, 01:23:28 от renzrv »

Оффлайн ALiEN

  • Администратор
  • Старожил
  • *
  • Сообщений: 6690
  • 20% Cooler
    • Просмотр профиля
Re: простой вопрос по bash
« Ответ #18 : 18 Декабря 2016, 01:29:15 »
Похоже если в левой части команда не успеет открыть и прочитать ВЕСЬ файл за время задержки, то файл будет пустым или будут не все данные:

Точно так и есть. греп файла 100 мб за 0.1s - у меня файл пустой. за минуту - нормально. В итоге, ТСу лучше брать промежуточный файл, нежели высчитывать время.

Заранее прошу прощения за непроверенные данные. 
🖥 AsRock B550M Pro4 :: AMD Ryzen 5 3600 :: 16 GB DDR4 :: AMD Radeon RX 6600 :: XFCE
💻 ACER 5750G :: Intel Core i5-2450M :: 6 GB DDR3 :: GeForce GT 630M :: XFCE

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
Re: простой вопрос по bash
« Ответ #19 : 18 Декабря 2016, 02:35:00 »
Вот придумал решение функцией для .bashrc:
Код: (bash) [Выделить]
Rwt(){
file="$1"
[ "$file" ] || { echo 'Не указан файл для перезаписи.' ; return 1 ; } || return 1
[ -f "$file" ] || { echo 'Не найден файл для перезаписи.' ; return 1 ; } || return 1
tmp_file="$(mktemp -u --tmpdir="$PWD")"
: > "$tmp_file"
[ -f "$tmp_file" ] || { echo 'Ошибка при создании временного файла.' ; return 1 ; } || return 1
cat > "$tmp_file"
mv "$tmp_file" "$file"
}
(добавить в конец .bashrc, перезапустить терминал/консоль)

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

Использование:
Код: (bash) [Выделить]
command1 file | command2 ... | Rwt file
Для примера ТС:
Код: (bash) [Выделить]
grep "ddd" f | Rwt f
« Последнее редактирование: 18 Декабря 2016, 02:45:53 от renzrv »

Оффлайн EvangelionDeath

  • Администратор
  • Старожил
  • *
  • Сообщений: 3487
  • Ubuntu 22.04 х64
    • Просмотр профиля
Re: простой вопрос по bash
« Ответ #20 : 28 Декабря 2016, 16:25:11 »
а не проще ли

Код: (bash) [Выделить]
grep 'pattern' <file_name> > /tmp/tmp_file; mv /tmp/tmp_file <file_name>

а то через cat перезаписывать файл - какой-то изврат
HP Pro 840 G3: Intel i5-6300U, 32GB DDR4 2133MHz, Intel 520, Intel Pro 2500 180GB/Ubuntu 22.04
Dell Latitude 5590: Intel i5-8350U, 16GB DDR4 2400MHz, Intel 620, Samsung 1TB/Ubuntu 22.04

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
Re: простой вопрос по bash
« Ответ #21 : 28 Декабря 2016, 17:02:22 »
Перезаписывает не cat, а mv - оригинальный файл - темп файлом.
cat только пишет в темп из стандартного ввода.

Цитировать
а не проще ли
Cравни:
Код: (bash) [Выделить]
grep 'pattern' f | Rwt fи
Код: (bash) [Выделить]
grep 'pattern' <file_name> > /tmp/tmp_file; mv /tmp/tmp_file <file_name>

 

Страница сгенерирована за 0.05 секунд. Запросов: 25.