Решено: построчное чтение файла. как?
Модератор: Модераторы разделов
-
Kornelius
- Сообщения: 86
- ОС: Linux/BSD/Netware/OpenSolaris
Решено: построчное чтение файла. как?
Всем драсте.
Подскажите как на bash'e реализовать следующее.
Есть файл input.txt такого содержания:
string1
string2
string3
string4
Нужно написать скрипт, который за один запуск извлечет из файла строку string1 и запишет ее в output.txt. Следующий запуск извлечет из файла строку string2 и запишет ее в output.txt.
Таким образом после 2-ух запусков у нас будет такое содержимое файлов:
input.txt
---------
string3
string4
output.txt
---------
string1
string2
Нужно именно на BASHе.
(Очень желательно оптимальный код)
Заранее спасибо.
Подскажите как на bash'e реализовать следующее.
Есть файл input.txt такого содержания:
string1
string2
string3
string4
Нужно написать скрипт, который за один запуск извлечет из файла строку string1 и запишет ее в output.txt. Следующий запуск извлечет из файла строку string2 и запишет ее в output.txt.
Таким образом после 2-ух запусков у нас будет такое содержимое файлов:
input.txt
---------
string3
string4
output.txt
---------
string1
string2
Нужно именно на BASHе.
(Очень желательно оптимальный код)
Заранее спасибо.
-
allez
- Сообщения: 2223
- Статус: Не очень злой админ :-)
- ОС: SuSE, CentOS, FreeBSD, Windows
Re: Решено: построчное чтение файла. как?
А в чем сакральный смысл данного действа? Или это вам такое задание в учебном заведении дали? Если да, то читайте про sed и перенаправление вывода в файл.
-
Kornelius
- Сообщения: 86
- ОС: Linux/BSD/Netware/OpenSolaris
Re: Решено: построчное чтение файла. как?
смысл в том, что я упростил здесь задачу, на самом деле файлик используется в качестве буфера (FIFO) и то что в него попадает, будет по мере возможности обрабатываться определенным образом.
sed? Чем он мне поможет вырезать(удалить) первую строку из файла, не трогая все остальные строки. Ведь их может быть очень много.
Проблема у меня именно в удалении первой строки из файла.
-
allez
- Сообщения: 2223
- Статус: Не очень злой админ :-)
- ОС: SuSE, CentOS, FreeBSD, Windows
Re: Решено: построчное чтение файла. как?
Читайте man sed на предмет команды "d".
Навскидку пока могу предложить это:
Код: Выделить всё
cat file | sed -n '1p' >> output.txt; sed -i '1d' file-
Reboot
- Сообщения: 321
- Статус: Красен глаз -- темна душа
Re: Решено: построчное чтение файла. как?
Kornelius, если FIFO в виде файла, то все просто, после прочтения всё само умрёт. head -n 1 например достаточно. или седом
Мой компьютер зовут Марвин
-
Kornelius
- Сообщения: 86
- ОС: Linux/BSD/Netware/OpenSolaris
Re: Решено: построчное чтение файла. как?
Читайте man sed на предмет команды "d".
Навскидку пока могу предложить это:
Код: Выделить всё
cat file | sed -n '1p' >> output.txt; sed -i '1d' file
cat file однозначно не катит, скрипт возможно будет вызываться несколько раз в секунду и обрабатывать файлик, содержащий тысячу строк. Система ляжет.
А на счет команды "d" щас почитаем.
Как так само? Поясните плз.
-
allez
- Сообщения: 2223
- Статус: Не очень злой админ :-)
- ОС: SuSE, CentOS, FreeBSD, Windows
Re: Решено: построчное чтение файла. как?
Код: Выделить всё
sed -n '1p' file >> output.txt; sed -i '1d' file-
Reboot
- Сообщения: 321
- Статус: Красен глаз -- темна душа
Re: Решено: построчное чтение файла. как?
файлик используется в качестве буфера(FIFO)
если это так, то почему бы не использовать непосредственно FIFO файл?
man fifo
Мой компьютер зовут Марвин
-
Kornelius
- Сообщения: 86
- ОС: Linux/BSD/Netware/OpenSolaris
Re: Решено: построчное чтение файла. как?
Я вообче надаялся, что может есть утиль какая для этого.
Видимо придется самому на C написать.
Видимо придется самому на C написать.
-
diesel
- Бывший модератор
- Сообщения: 5989
- ОС: OS X, openSuSE, ROSA, Debian
Re: Решено: построчное чтение файла. как?
вообще напоминает вопрос на контрольной, которых мы не любим
Ненадежный способ(то есть если в строках есть спецсимволы которые могут интепретироваться как куски регулярного выражения что-то может пойти не так; если строки повторяются, то тоже пойдет не так)
Код: Выделить всё
#!/bin/bash
cat input.txt | while read i; do
grep -E "^$i$" output.txt || {
echo $i >> output.txt
sed -i -e "/$i/d" input.txt
break
}
done-
Kornelius
- Сообщения: 86
- ОС: Linux/BSD/Netware/OpenSolaris
Re: Решено: построчное чтение файла. как?
Спасибо за вариант - надо обдумать.
Хотя скорее всего не подойдет по причине возможной потери данных в случае сбоя, зависания
компа и т.п. Файлик как то надежнее.
-
diesel
- Бывший модератор
- Сообщения: 5989
- ОС: OS X, openSuSE, ROSA, Debian
Re: Решено: построчное чтение файла. как?
Kornelius писал(а): ↑03.01.2009 23:28Читайте man sed на предмет команды "d".
Навскидку пока могу предложить это:
Код: Выделить всё
cat file | sed -n '1p' >> output.txt; sed -i '1d' file
cat file однозначно не катит, скрипт возможно будет вызываться несколько раз в секунду и обрабатывать файлик, содержащий тысячу строк. Система ляжет.
убери cat. можно sed -n '1p' filename
-
Kornelius
- Сообщения: 86
- ОС: Linux/BSD/Netware/OpenSolaris
Re: Решено: построчное чтение файла. как?
diesel писал(а): ↑03.01.2009 23:32
вообще напоминает вопрос на контрольной, которых мы не любим
Ненадежный способ(то есть если в строках есть спецсимволы которые могут интепретироваться как куски регулярного выражения что-то может пойти не так; если строки повторяются, то тоже пойдет не так)
Код: Выделить всё
#!/bin/bash cat input.txt | while read i; do grep -E "^$i$" output.txt || { echo $i >> output.txt sed -i -e "/$i/d" input.txt break } done
Интересный вариант. А Вы случайно не знаете как действует эта схема с pipe - в смысле файл input.txt сразу будет прочитан илил постепенно считываться порциями и что будет если во время работы этого скрипта в файл будут продолжать писаться данные.
-
diesel
- Бывший модератор
- Сообщения: 5989
- ОС: OS X, openSuSE, ROSA, Debian
Re: Решено: построчное чтение файла. как?
скорее всего будет прочитан как только так сразу. лучше вариант с sed'ом - если предполагается что это надо часто и быстро. Как вариант sed '1p' можно использовать head -1 filename(данные ведь пишутся в конец файла?)
-
allez
- Сообщения: 2223
- Статус: Не очень злой админ :-)
- ОС: SuSE, CentOS, FreeBSD, Windows
Re: Решено: построчное чтение файла. как?
сравнение быстродействия с cat и без оного
03:39 home:~/tmp $ wc -l file
1523 file
03:39 home:~/tmp $ time ( sed -n '1p' file >> output.txt; sed -i '1d' file )
real 0m0.062s
user 0m0.036s
sys 0m0.020s
03:39 home:~/tmp $ time ( sed -n '1p' file >> output.txt; sed -i '1d' file )
real 0m0.059s
user 0m0.040s
sys 0m0.020s
03:39 home:~/tmp $ time ( sed -n '1p' file >> output.txt; sed -i '1d' file )
real 0m0.059s
user 0m0.048s
sys 0m0.012s
03:39 home:~/tmp $ time ( cat file | sed -n '1p' >> output.txt; sed -i '1d' file )
real 0m0.070s
user 0m0.032s
sys 0m0.032s
03:39 home:~/tmp $ time ( cat file | sed -n '1p' >> output.txt; sed -i '1d' file )
real 0m0.069s
user 0m0.028s
sys 0m0.028s
03:39 home:~/tmp $ time ( cat file | sed -n '1p' >> output.txt; sed -i '1d' file )
real 0m0.066s
user 0m0.032s
sys 0m0.024s
Как видим, на обработку файла в полторы тысячи строк уходит меньше одной десятой секунды. Процессор - AMD Athlon™ 64 X2 Dual Core Processor 4200+.
-
Kornelius
- Сообщения: 86
- ОС: Linux/BSD/Netware/OpenSolaris
Re: Решено: построчное чтение файла. как?
ОК. Буду пробовать
Всем спасибо и за опцию "d" в сиде отдельное спасибо. Надо маны лучше курить, полагаю что
сид можно будет ограничить удалением первой найденой строки, а не всех подобных строк во всем файле.
Жалко правда что нет такой утилиты и приходится огород городить, а я так надеялся.
-
Kornelius
- Сообщения: 86
- ОС: Linux/BSD/Netware/OpenSolaris
Re: Решено: построчное чтение файла. как?
Нашел приемлемое решение.
Если вдруг кому будет интересно, то вот:
или лучше:
Спасибо allezу
Если бы можно было упростить до:
то было бы самое то что нужно.
Если вдруг кому будет интересно, то вот:
Код: Выделить всё
head -n 1 input.txt>>output.txt; sed -i "1d" input.txtили лучше:
Код: Выделить всё
sed "q" input.txt>>output.txt; sed -i "1d" input.txtСпасибо allezу
Если бы можно было упростить до:
Код: Выделить всё
sed -i "1d" input.txt>>output.txtто было бы самое то что нужно.
-
кодировщик
- Сообщения: 974
- Статус: зарёган в пятницу 13
- ОС: Linux
Re: Решено: построчное чтение файла. как?
А можно это как модифицировать чтобы вывести случайную строку?!
-
diesel
- Бывший модератор
- Сообщения: 5989
- ОС: OS X, openSuSE, ROSA, Debian
Re: Решено: построчное чтение файла. как?
кодировщик писал(а): ↑09.01.2009 22:51А можно это как модифицировать чтобы вывести случайную строку?!
если не думать:
Код: Выделить всё
rand=$(perl -e "print int(rand($(wc -l $filename|awk '{print $1}')))" ); sed -n "${rand}p" $filename-
кодировщик
- Сообщения: 974
- Статус: зарёган в пятницу 13
- ОС: Linux
Re: Решено: построчное чтение файла. как?
diesel писал(а): ↑09.01.2009 23:25кодировщик писал(а): ↑09.01.2009 22:51А можно это как модифицировать чтобы вывести случайную строку?!
если не думать:
Код: Выделить всё
rand=$(perl -e "print int(rand($(wc -l $filename|awk '{print $1}')))" ); sed -n "${rand}p" $filename
неа, чот не выходит.
-
diesel
- Бывший модератор
- Сообщения: 5989
- ОС: OS X, openSuSE, ROSA, Debian
Re: Решено: построчное чтение файла. как?
кодировщик писал(а): ↑10.01.2009 23:20diesel писал(а): ↑09.01.2009 23:25кодировщик писал(а): ↑09.01.2009 22:51А можно это как модифицировать чтобы вывести случайную строку?!
если не думать:
Код: Выделить всё
rand=$(perl -e "print int(rand($(wc -l $filename|awk '{print $1}')))" ); sed -n "${rand}p" $filename
неа, чот не выходит.
что конкретно?
Код: Выделить всё
diesel@debian:/tmp$ filename=test.txt
diesel@debian:/tmp$ rand=$(perl -e "print int(rand($(wc -l $filename|awk '{print $1}')))+1" ); echo $rand; sed -n "${rand}p" $filename
2
string2
diesel@debian:/tmp$ rand=$(perl -e "print int(rand($(wc -l $filename|awk '{print $1}')))+1" ); echo $rand; sed -n "${rand}p" $filename
3
string3
diesel@debian:/tmp$ cat test.txt
string1
string2
string3
string4