Я хочу разделить свой$файлсодержащийИксстроки пополам и проверьте, сколько строк содержат "мертвый" в журнале. Я начал со следующего:
half=`expr $(egrep -c . $file) / 2`
sed -n 1,${half}p $file |
xargs echo $file $half $(egrep -c dead $I) > log_1
sed -n ${half},${egrep -c . $file}p |
xargs echo $file $half $(egrep -c dead $I) > log_2
Вывод для первой sed
команды в порядке, но при замене egrep
в диапазоне sed
происходит ошибка:
DeadOrAlive 5 2
-bash: ${half},${egrep -c . $file}p: bad substitution
Есть ли более эффективный способ разбить файл на bash
?
решение1
Используя
wc
,head
иtail
:half=$(( $(wc -l "$file")/2 )) head -$half | egrep -c dead | xargs echo "$file" $half > log_1 tail -$half | egrep -c dead | xargs echo "$file" $half > log_2
С использованием
split
:split -a1 --numeric-suffixes=1 -n 'l/2' "$file" "$file"_ echo "$file" "$file"_1 $(egrep -c dead "$file_1") > log_1 echo "$file" "$file"_2 $(egrep -c dead "$file"_2) > log_2 rm "$file"_[12]
решение2
Вот решение на Awk.
awk '/dead/ { a[++n] = NR }
END { for (i=1; i<=n; i++) if (a[i] > NR/2) break
print ARGV, int(NR/2), i-1 >"log_1";
print ARGV, int(NR/2)+(int(NR/2)!=NR/2), n-i+1 >"log_2" }' file
Мы собираем в массив a
номера строк совпадений. Затем мы выясняем, сколько номеров строк в массиве меньше самой средней строки; их количество присваивается первому разделу. (Мы должны использовать , i-1
потому что мы уже прошли точку разделения, когда выходим break
из цикла.)
В общем случае следует избегать многократного перечитывания одного и того же файла, особенно если он может быть большим; а во-вторых, постараться минимизировать количество процессов.
Неясно, что вы ожидаете увидеть в среднем поле вывода. Если файл содержит нечетное количество строк, то первая «половина» будет содержать на одну строку меньше, чем второй раздел. (Это несложно изменить, но вам нужно решить, как поступить.)