Вот еще один sed
:
sed '/^---/,/---$/{H;/^---/h;/---$/!d;x;s/\n/ /g;}' infile
он использует диапазон и буфер хранения. Он добавляет каждую строку в этом диапазоне в буфер удержания, перезаписывая ее, если это начало диапазона; он удаляет строку, если это не конец диапазона, иначе он обменивается буферами и заменяет все новые строки пробелами.
И другой подход с ed
:
ed -s infile <<\IN
?^---?,.-s/$/ /
?^---?,$j
1,/---$/-s/$/ /
1,/---$/j
w
q
IN
В нем используются четыре диапазона: сначала поиск выполняется в обратном направлении ( ed
начинается с конца файла) и добавляет пробел в конец каждой строки в первом диапазоне, а затем соединяет строки во втором диапазоне (которые на самом деле являются строками в первом плюс еще одна строка); затем он делает то же самое, но начиная с начала файла.
lsof
имеет формат вывода для "постобработки" с параметром -F
(см. Раздел ВЫХОД ДЛЯ ДРУГИХ ПРОГРАММ в руководстве ).
lsof -nPMp "$pid" -Fn | sed '
\|^n/|!d
s/ type=STREAM$//; t end
s/ type=DGRAM$//; t end
s/ type=SEQPACKET$//
: end
s|^n||'
Выведет список открытых файлов, которые разрешаются в путь в файловой системе.
-nPM
отключает часть обработки, которую lsof
выполняет по умолчанию и которая здесь не важна, например, разрешение IP-адресов, портов или имен rpc. -p "$ pid"
, укажите процесс, чьи открытые файлы нужно перечислить -Fn
: по выходным полям. Спросите часть n . | sed
постпроцесс с sed
, чтобы выбрать только интересующую нас часть: \ | ^ n / |! d
: пропустить все, что не начинается с n /
s / type = ... $ /; t end
: удалить эти строки в конце строки и в случае успеха перейти к метке end
. : конец
: метка конец
. s | ^ n ||
: удалить начальный символ n
, который lsof
вставляет для идентификации выводимого поля. Однако обратите внимание, что непечатаемые символы в именах файлов кодируются (например, \ n
для новой строки, ^ [
для ESC ...) неоднозначным образом (как в ^ [
может означать либо ^ [
и ESC).
Кроме того, для удаленных файлов, по крайней мере, в Linux, вы все равно получите путь к файлу, но с добавлением (удалено)
. Опять же, нет способа отличить удаленный файл от файла, имя которого заканчивается на (удалено)
.Просмотр количества ссылок не обязательно поможет, поскольку удаленный файл может быть связан в другом месте.
См. Также удаление type = *
, которое мы делаем для сокетов домена Unix, которое могло действительно иметь место в имени файла.
Это означает, что, хотя это будет работать в большинстве случаев, вы не можете надежно постобработать этот вывод в общем случае.
Не говоря уже о том, что lsof
сам может не правильно проанализировать информацию, возвращаемую ядром, или что ядро может не предоставить эту информацию в надежно анализируемом формате