Разделить файл на несколько файлов по шаблону [дубликат]

Если вы хотите предварительно заполнить содержимое в редакторе, запишите это исходное содержимое в файл, как вы думали.

Невозможно «перевести редактор в состояние, в котором он был бы, если бы вы набрали несколько строк после его открытия», который работает с различными редакторами. Во многих редакторах это означает, что файл не будет сохранен, но не существует единого способа достижения этого состояния, и есть редакторы, в которых вообще нет этой концепции (например, Scratch ).

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

file=$(mktemp)
cat <"$file"
Hello
world
EOF
old_metadata=$(ls -li "$file")
"${VISUAL:-"${EDITOR:-vi}"}" "$file"
new_metadata=$(ls -li "$file")
if [ "$new_metadata" = "$old_metadata" ]; then
  … # unchanged file, abandon operation
else
  … # modified file, carry on
fi

Помните, что если файл был изменен, но размер и индексный дескриптор не изменились, а модификация заняла менее 1 секунды, этот сценарий будет считать, что файл не был изменен. Этого не произойдет, если человек редактирует, но это может легко произойти, если $ EDITOR - это сценарий, который автоматически отправляет измененный файл. Трудно сделать лучше портативным способом.В GNU coreutils передача опции - full-time в ls решает эту проблему, если файловая система поддерживает субсекундные временные метки с достаточной точностью.

Или проверьте, был ли файл изменен. Переносимый способ сделать это - сохранить копию исходного содержимого и вызвать cmp . Если доступны такие команды, как sha256sum или sha , вы можете использовать их и сравнивать хэши до и после. Вы все равно можете считать файл отредактированным, если его временная метка изменилась - возможно, пользователь действительно хотел отправить ввод по умолчанию.

Эту технику используют некоторые системы контроля версий, когда запускают редактор для редактирования сообщения о фиксации. Если пользователь не сохраняет файл, фиксация прерывается.

Если вы также хотите поместить курсор в конец ввода, универсального способа сделать это не существует. Во многих редакторах вы можете написать

"$EDITOR" +"$line" "$file"

, и редактор откроется с курсором на указанной строке. Это поддерживается многими редакторами, включая vi (все варианты), emacs, joe и gedit, но не kwrite.

5
17.02.2016, 21:11
2 ответа
NEEDLE=ABC
HAYSTACK=/path/to/bigfile
csplit -f splitfile_ $HAYSTACK /$NEEDLE/ "{$(($(grep -c $NEEDLE HAYSTACK)-1))}"
for file in splitfile_*; do
    sed --in-place "s/$NEEDLE//" $file
done

Вышеупомянутое разделит файл по запросу, независимо от того, сколько экземпляров строки маркера у вас есть, а затем удалит маркер из результирующих файлов. Выходные файлы будут называться e. грамм. splitfile_00 , splitfile_01 и так далее.

Разделение этого бита в конце вызова csplit : "{$ (($ (grep -c $ NEEDLE HAYSTACK) -1))}" : мы используем подоболочка grep , чтобы получить количество экземпляров вашего маркера в файле, и вычесть единицу - это сообщает csplit точно, сколько разбиений он будет делать.

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

1
27.01.2020, 20:37

Использование csplit

csplit -z somefile /ABC/ '{*}'

Выходные файлы будут xx00 , xx01 , ...по умолчанию, но вы можете изменить формат и нумерацию, если хотите - см. man csplit

20
27.01.2020, 20:37

Теги

Похожие вопросы