Сегодня я столкнулся с этой проблемой на своем ноутбуке Lenovo Yoga 730 с диском ADATA NVMe 512G. У меня были ошибки при запуске mkfs.ext4, но он завершился. Как только я попытался смонтировать раздел, я получил ту же ошибку, что и описанная.
Я попробовал версию Arch от мая 2019 г., и проблем не возникло. Кажется, проблема появилась в выпуске за июнь 2019 года. Используя ISO-образ от мая 2019 года, я смог успешно установить Arch на свой диск NVMe. Версия ядра после установки: 5.2.4 -arch1 -1 -ARCH.
Ваша проблема не в том, что sed -i
создает много временных файлов, а в том, что вы запускаете его много раз с одним и тем же входным файлом, и каждый из них создает временный файл для вывода, как показано в strace
:
execve("/bin/sed", ["sed", "-i", "-e", "", "/tmp/foo"], 0x7fff10da5288 /* 36 vars */) = 0
openat(AT_FDCWD, "/tmp/foo", O_RDONLY) = 3
openat(AT_FDCWD, "/tmp/sedVdjaBk", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
rename("/tmp/sedVdjaBk", "/tmp/foo") = 0
+++ exited with 0 +++
Решение состоит в том, чтобы запустить sed -i
только один раз.
Для этого начните с написания команды sed
, которая преобразует ваш входной файл в программу sed
. Это будет выглядеть примерно так:
sed -e 's!.*!s/install, element = &, at=/install, element = &, at= -0.001 +/g!"
(Возможно, мы могли бы улучшить это, если бы входной файл содержал значимые символы регулярного выражения -, например. s/install, element = &, at=/\& -0.001 +/g
, но это выходит за рамки данного вопроса ).
Протестируйте это, чтобы убедиться, что полученный скрипт вас устраивает.
Затем нам нужно получить другой sed
для использования этого преобразованного текста в качестве файла программы. Мы можем сделать это, сказав ему прочитать свою программу из стандартного ввода (, хотя есть альтернативы¹):
sed -e 's!.*!s/install, element = &, at=/install, element = &, at= -0.001 +/g!' \
shiftLeft.txt |
sed -f - -i processedFiles/layoutDB.seq
Опять же, протестируйте это (без флага -i
), пока не убедитесь, что оно делает то, что вы хотите.
¹ Поскольку мы используем bash , мы можем использовать подстановку процесса:
sed -f <(sed -e 's!.*!s/install, element = &, at=/install, element = &, at= -0.001 +/g!' shiftLeft.txt) \
-i processedFiles/layoutDB.seq
В стандартной оболочке нам нужно было бы захватить преобразованный текст в виде строки и предоставить его в виде командного -строкового скрипта:
sed -e "$(sed -e 's!.*!s/install, element = &, at=/install, element = &, at= -0.001 +/g!' shiftLeft.txt)" \
-i processedFiles/layoutDB.seq
Не вызывайте повторно sed в цикле оболочки, просто вызовите awk один раз, например. (не проверено, так как вы не предоставили образец ввода/вывода для тестирования )с использованием GNU awk для редактирования «на месте» и 3-го аргумента для соответствия():
awk -i inplace '
NR==FNR { lines[$0] }
(FNR>NR) && match($0,/(.*install, element = )([^,]+)(, at=)/,a) && (a[2] in lines) {
$0 = a[0] " -0.001 +"
}
{ print }
' shiftLeft.txt processedFiles/layoutDB.seq
Может быть лучший способ сделать это в зависимости от того, как выглядит ваш ввод/вывод.