Я хочу разделить мой файл $, содержащий x строк пополам, и проверить, сколько строк содержат « мертвые » в журнале. Я начал со следующего:

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?

2 ответа2

0
  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
    
  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]
    
0

Вот решение 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 из цикла.)

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

Непонятно, что вы ожидаете от среднего поля вывода. Если файл содержит нечетное количество строк, первая "половина" будет содержать на одну строку меньше, чем второй раздел. (Это не сложно изменить, но вы должны решить, так или иначе.)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .