Дуже часто в мене виникає потреба обробляти якийсь файл по рядково. Звичайно тут нема ніякої проблеми, ось код:
#!/bin/bash cat file.txt | while read line; do echo $line done
Але що робити коли файл меговеликий і його обробка триває декілька хвилин, годин або днів (мається на увазі що кожен рядок з файлу піддається довготривалій обробці)???
Коли що небудь або хто небудь перериває цей процес то це мене дуже бісить. Тому виникла потреба в скрипті який би міг вирізати з файлу той рядок який йому потрібно, тобто з’їдати файл.
А якщо добавити прапорець блокування під час зчитування рядка з файла то цей скрипт набуває зовсім нових властивостей
Переваги такого скрипту:
- можна легко відновити роботу після переривання
- можна запустити n-кількість копій, які швидше "з’їдять" файл
- не треба змінювати коди копій скрипту, всі коди однакові - а кожна копія робить своє
Ось детальний код з коментуванням:
#!/bin/bash FILE="file-e" # файл-жертва SIZE=`cat $FILE | wc -l` # поки розмір файлу не дорівнює 0 while [ "$SIZE" != "0" ]; do LOCK=`head -n 1 lock`; # зчитуєм блокування if [ "$LOCK" == "0" ]; then echo 1 > lock # якщо розблоковано, блокувати і... SIZE=`cat $FILE | wc -l` { IFS= read -r line; cat } < "$FILE" > "tmp_$SIZE" && mv "tmp_$SIZE" "$FILE" # ось ці три рядки вище роблять наступне: # - зчитують верхній рядок в змінну line # - решту файла заноситься в тимчасовий файл # - потім тимчасовий файл переміщується в оригінал echo 0 > lock # розблоковуєм DATE=`date +%T` echo "${DATE} ${line}" sleep 1 else echo "Waiting for UNLOCKING..." # якщо заблоковано, очікування 3 сек sleep 3 fi done; # і знову на початок циклу, поки файл не закінчиться
А тепер треба перевірити роботу цього пожирача. В якості піддослідного файла-жертви буде файл ось такої структури:
1 stringЯкий створюється скриптом rst.sh. Менше слів, більше коду:
2 string
3 stirng
...
flashbag@laptop:~/vnc-new$ cat rst.sh #!/bin/bash rm -rf file-e touch file-e chmod 666 file-e for i in `seq 1 50`; do echo "${i} string" >> file-e done flashbag@laptop:~/vnc-new$ ./rst.sh flashbag@laptop:~/vnc-new$ cat file-e 1 string 2 string 3 string 4 string 5 string 6 string
Тепер запускаю 4 копії цього мегопожирача файлів...
Як видно з скріншота кожна копія цього мегопожирача з’їдає один унікальний рядок. Дві копії не можу з’їсти один і той самий рядок. Ще один експеримент на рахунок продовження трапези скрипта після переривання.
Ця стаття не принесе нічого нового в досвід затятих лінуксоїдів, тому що вона розрахована на аматорів-початківців у bash програмуванні. Буду радий почути відгуки :)
