LINUX.ORG.RU

BASH oчень долго выполняется цикл for

 , ,


1

1

Существует файл в котором более 8млн строк, в этих строках выводится время формата ЧЧ:ММ:СС через рандомное количество строк, нужно чтобы время было записано слева от строки. Цикл работает, но выполнение занимает более 4х часов. Помогите пожалуйста ускорить цикл & wait по разному пробовал только увеличивают время выполнения…..

File="/home/user/Desktop/FLY.txt"
Lines=$(cat $File)
a=":"
for Line in $Lines
do
Sr=`expr substr $Line 3 1`
 if [ "$Sr" == "$a" ] 
then
    Time=$Line
    else
       echo -e "$Time\t$Line"
    fi
done    >FLY_fin.txt


Последнее исправление: max27_09 (всего исправлений: 4)

Не надо считывать файл в переменную Lines

надо:

while read Line; do
...
done < FLY.txt

Я не буду говорить о том что можно было исп. sed вместо этого bash-цикла

futurama ★★★★★
()
Последнее исправление: futurama (всего исправлений: 1)

`expr substr $Line 3 1`

Если у тебя bash (а не какой-то sh), лучше использовать встроенные методы: ${Line:3:1}

Вместо одинарных скобок - двойные: if [[ "$Sr" == "$a" ]]

Вроде этого будет достаточно, чтобы не плодить процессы в цикле (а причина такой медленности - в этом).

TheAnonymous ★★★★★
()
sed -e 's/\(^..:.*\)/Time:\t\1/' /home/user/Desktop/FLY.txt >FLY_fin.txt

выражение для поиска строк со временем можно и улучшить, но вроде и не требуется…

Elyas ★★★★★
()
Ответ на: комментарий от futurama

Это не массив

Странно, а работа идёт как с массивом.

Lines=$(cat $File)
a=":"
for Line in $Lines
...

В его случае в цикле ФОР вся эта мега-строка побьётся по пробелам, без разницы как он там дальше делает.

Он в начале большой файл считывает.

kostik87 ★★★★★
()
Ответ на: комментарий от kostik87

Пайп в while read не даёт установить переменные за пределами цикла. Нужно либо while ... done<file, либо for, который может нагадить в зависимости от контента файла.

Ну и да, IFS. По умолчанию IFS пуст, а значит "строка" в данном случае будет словом до первого пробела/таба/ньюлайна.

mord0d ★★★★★
()

[i]Существует файл в котором более 8млн строк[/i] Думаю в этом проблема. есть такая штука называется «база данных» погугли. Велосипед уже изобрели.

antech
()
Ответ на: комментарий от mord0d

Ну и да, IFS. По умолчанию IFS пуст, а значит «строка» в данном случае будет словом до первого пробела/таба/ньюлайна.

Строка будет полной строкой из входного файла.

kostik87 ★★★★★
()
Ответ на: комментарий от mord0d

не даёт установить переменные за пределами цикла

Ну правильнее - прочитать. Впрочем, ваш оппонент всё равно ничего не понял :)

По умолчанию IFS пуст

Нет, конечно.

printf "%q\n" "$IFS"
$' \t\n'

в данном случае будет словом до первого пробела/таба/ньюлайн

Нет, конечно, строка в последнюю перменную/единственную считывается до -d символ_конца_строки, который по умолчанию \n.

vodz ★★★★★
()
Ответ на: комментарий от vodz

не даёт установить переменные за пределами цикла

Ну правильнее - прочитать.

И прочитать тоже, но не все. Экспортированные таки даёт.

По умолчанию IFS пуст

Нет, конечно.

unset IFS даёт тот же результат.

Нет, конечно, строка в последнюю перменную/единственную считывается до -d символ_конца_строки, который по умолчанию \n.

Это какой-то фбашизм…

mord0d ★★★★★
()
Ответ на: комментарий от mord0d

Экспортированные таки даёт.

Нет конечно, в новом процессе пайпа и неэкспортированые также передаются в шел, экспорт влияет только для внешних команд к шелу. А вот прочитать изменение переменных после завершения суброцесса также невозможно и экспорт ничем не поможет.

unset IFS даёт тот же результат.

Нет конечно. Результат разный и описан в документации. Да, там много схожего, но так всегда, когда есть разные способы, то и отличия должны быть, хоть и минимальные, иначе для чего тогда вообще делать разное.

Это какой-то фбашизм…

Вот всё так у вас. Знаний не хватает, чтобы спорить, говорите чушь.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 2)