Программа, вспомогательная это man
и git diff
вызовите назван пейджером. В современных системах называют пейджер по умолчанию less
. Несколько десятилетий назад первый пейджер был more
, так называемый, потому что это отобразило одну страницу затем, ожидал Вас для нажатия клавиши для наблюдения “больше”. Затем прибыл less
, которые также позволяют Вам возвратиться (для наблюдения меньше, так сказать), подтверждая высказывание, что “меньше - больше” (чем больше).
git diff
определенное исключение; diff
утилита, cvs diff
подкоманда, svn diff
подуправляйте и так далее просто делают их задание вычислений разности и распечатывания это. Если Вы хотите пролистать разность, необходимо вызвать пейджер явно:
diff file.old file.new | less
Если Вы хотите использовать другой пейджер для man
, git diff
и другие команды, которые называют пейджер, можно установить PAGER
переменная среды, например, путем помещения этого в файл ~/.profile
:
export PAGER=most
Вы не можете сделать команды таким как diff
вызовите пейджер автоматически. Можно сделать функцию обертки хотя (чтобы быть помещенным в файл инициализации оболочки, например. ~/.zshrc
для zsh или ~/.bashrc
для удара):
diff () {
if [ -t 1]; then # If standard output is a terminal
command "$@" | less # then pipe through less
else # else
command "$@" # run the command (and return its exit status)
fi
}
Предупреждение: такая функция может иногда быть разрушительной. Можно также сделать псевдоним с одним символом для пейджера, например.
alias p=less P=less
таким образом, можно ввести diff … |p
или diff … |P
когда Вы хотите пролистать вывод команды.
Вы нашли ошибку в ударе, своего рода. Это - известная ошибка с известной фиксацией.
Программы представляют смещение в файле как переменная в некотором целом типе с конечным размером. В былые времена все использовали int
для примерно всего, и int
тип был ограничен 32 битами, включая знаковый бит, таким образом, он мог сохранить значения от-2147483648 до 2147483647. В наше время существуют названия другого типа разных вещей, включая off_t
для смещения в файле.
По умолчанию, off_t
32-разрядный тип на 32-разрядной платформе (позволяющий до 2 ГБ) и 64-разрядный тип на 64-разрядной платформе (позволяющий до 8EB). Однако распространено скомпилировать программы с опцией LARGEFILE, которая переключает тип off_t
к 64 бита шириной быть и выполняет вызов программы подходящие реализации функций такой как lseek
.
Кажется, что Ваш выполняют удар на 32-разрядной платформе, и Ваш двоичный файл удара не компилируется с большой поддержкой файла. Теперь, когда Вы читаете строку из регулярного файла, колотите, использует внутренний буфер для чтения символов в пакетах для производительности (для получения дополнительной информации, посмотрите источник в builtins/read.def
). Когда строка завершена, вызовы удара lseek
перематывать файловое смещение назад к позиции конца строки, в случае, если некоторая другая программа, о которой заботятся о положении в том файле. Вызов к lseek
происходит в zsyncfc
функция в lib/sh/zread.c
.
Я не считал источник в большом количестве деталей, но я предполагаю, что чего-то не происходит гладко при переходе, когда абсолютное смещение отрицательно. Таким образом, удар заканчивает тем, что читал при неправильных смещениях, когда он снова наполняет свой буфер, после того, как он передал метку на 2 ГБ.
Если мое заключение является неправильным, и Ваш удар на самом деле работает на 64-разрядной платформе или скомпилированный с поддержкой largefile, которая является определенно ошибкой. Сообщите об этом своему распределению или в восходящем направлении.
Оболочка не является правильным инструментом для обработки таких больших файлов так или иначе. Это будет медленным. Используйте sed, если это возможно, иначе awk.
Я не знаю о несправедливости, но это является, конечно, замысловатым. Если Ваши входные строки похожи на это:
YYYY-MM-DD some text ...
Затем нет действительно никакой причины этого:
new_file=${line:0:4}-${line:5:2}-${line:8:2}_file.log
Вы делаете большую работу подстроки для окончания с чем-то, что смотрит... точно способ, которым это уже смотрит в файле. Как насчет этого?
while read line; do
new_file="${line:0:10}_file.log"
echo "$line" >> $new_file
done
Это просто захватывает первые 10 символов от строки. Вы могли также обойтись без bash
полностью и просто используйте awk
:
awk '{print > ($1 "_file.log")}' < file.log
Это захватывает дату в $1
(первый разграниченный пробелом столбец в каждой строке) и использование это для генерации имени файла.
Обратите внимание, что возможно, что существуют некоторые поддельные строки журнала в Ваших файлах. Таким образом, проблема может быть с входом, не Вашим сценарием. Вы могли расшириться awk
сценарий для установки флага поддельных строк как это:
awk '
$1 ~ /[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/ {
print > ($1 "_file.log")
next
}
{
print "INVALID:", $0
}
'
Это пишет соответствие строк YYYY-MM-DD
к Вашим файлам журнала и строкам флагов, которые не запускаются с метки времени на stdout.
cut -c 1-10 file.log | uniq -c
дает мне ожидаемый результат. Я использую ${line:0:4}-${line:5:2}-${line:8:2}
потому что я помещу файл в каталог ${line:0:4}/${line:5:2}/${line:8:2}
, и я упростил проблему (я обновлю проблемный оператор). Я знаю awk
может помочь мне здесь, но я работал в других проблемах с помощью него. То, что я хочу, понимают проблему с bash
, не находят альтернативные решения.
– jfg956
01.03.2012, 22:54
cut
оператор, который работает. Поскольку я хочу сравнить яблоки с яблоками, не с апельсинами, я должен сделать вещи максимально подобными.
– jfg956
01.03.2012, 23:00
Походит на то, что Вы хотите сделать:
awk '
{ filename = substr($0, 0, 10) "_file.log"; # input format same as output format
if (filename != lastfile) {
close(lastfile);
print 'finished writing to', lastfile;
}
print >> filename;
lastfile=filename;
}' file.log
close
мешает открытой таблице файлов заполняться.