#perl #vim #file-format
#perl #vim #формат файла
Вопрос:
Я пишу программу на Perl для добавления r n в качестве 201-го и 202-го байтов в конце 200-байтовой записи. Я пытаюсь сделать это таким образом:
use constant REPORT_LINE_LEN => 200;
while(($rc = read $infile, $report_line, REPORT_LINE_LEN(), 0) != 0)
{
chomp $report_line;
$report_line .= "rn" . "n";
print $outfile $report_line;
}
Символ возврата каретки ^M находится в позиции 201, и мне нужен символ n в 202, но, похоже, я не могу поместить его туда, не увеличив длину записи более чем на 202 байта. Я проверяю местоположение ^M с помощью vim, что указывает на то, что файл все еще находится в формате Unix.
Я искал много источников, и я в тупике. Любая помощь будет оценена, включая то, как последние два байта могут отображаться в vim.
Я подтверждаю длину записи в vim, нажимая ‘$’, чтобы добраться до конца строки. Прямо сейчас там написано 201. Я также использую head -n 1 rmvtape.out | wc -c
для подтверждения длины записи, где rmvtape.out
находится файл, содержащий эти записи. Длина равна 202
.
Итак, является ли ^M невидимым в vim в этом случае?
Комментарии:
1. Убедитесь, что ваш выходной файл использует
binmode
. Тогда должно быть достаточно просто выполнить «r n».2. Не могли бы вы подробнее рассказать о том, как вы проверяете длину своей записи? Кроме того, как долго «более 202 байт»?
3. @Mr.Llama только что отредактировал файл с ответом.
4. Попробуйте
head -c 202 rmvtape.out | od -ax
. Это даст вам шестнадцатеричный дамп строки, который должен помочь вам разобраться с вашими проблемами длины. Обратите внимание, что я используюhead -c 202
, потомуhead -n 1
что разделится на первомn
, который технически является частью записи.
Ответ №1:
$report_line .= «r n» . «n»;
Вы добавляете здесь три символа, например r
, n
и еще n
один . Опустите последнее n
, и все должно быть хорошо, например:
$report_line .= "rn";
Комментарии:
1. @Steffen_Ulrich Я пробовал это, но количество позиций в vim возвращается к 200, а ^M в vim отсутствует. Тип по-прежнему unix.
2. попробуйте
warn unpack("H*",$report_line)
увидеть октеты, которые действительно находятся в строке, и проверьте длину сlength($report_line)
помощью . Если они дают правильные значения, то$output
это ваша проблема, например, используйте binmode, как предложил @Miller. И не доверяйте vim, используйте hexdump, чтобы увидеть, что там на самом деле.3. @Steffen_Ulrich В результате вашего метода получается 202 байта. Подтверждено с помощью hexdump.
4. Я ценю ответ и комментарии. Это в основном говорит мне о том, что первоначально считалось, что это терминаторы записи, а не часть записи.
5. Если ^M присутствует в выходных данных, но отсутствует в Vim, то, вероятно, Vim фактически определяет файл как формат dos. Вы уверены, что значение Vim для ‘fileformat’ при загрузке этого файла действительно остается равным «unix»? Если каждая строка заканчивается на rn, то Vim по умолчанию загрузит ее в формате DOS.