Команда updatedb
просканирует файловые системы в вашей системе и создаст индекс имен доступных файлов и каталогов. Эта индексация выполняется от имени непривилегированного пользователя -. Это означает, что индекс всегда будет содержать только имена файлов, которые доступны всем пользователям системы.
Поскольку ваш домашний каталог доступен только вам, (вы говорите в комментариях, что у вас есть rwx------
разрешения на него ), это означает, что он не будет проиндексирован пользователем updatedb
. Это, в свою очередь, означает, что locate
никогда не будет возвращать имена из вашего домашнего каталога. (использование sudo locate
вместо простого locate
по-прежнему будет запрашивать тот же индекс, так что это не поможет ).
Чтобы решить эту проблему, у вас есть два варианта:
Ослабьте ограничения для вашего домашнего каталога (и для любого каталога ниже того, который вы хотите проиндексировать,updatedb
). Права доступа, вероятно, должны читаться как rwxr-xr-x
или 755 в восьмеричном формате.
Не используйте locate
для поиска файлов.Вместо этого используйтеfind
:
find "$HOME" -name test.txt
Это будет искать что-либо с именем test.txt
в вашем домашнем каталоге или под ним.
Вы можете собрать все строки, начиная со строки abc
в резервном пространстве, а затем использовать жадный характер .*
, чтобы удалить все после последнейmno
:
sed '/abc/,$!d;H;$!d;x;s/\n//;s/\(.*mno[^\n]*\).*/\1/'
/abc/,$!d
— d
удалить все до первой abc
строки (или весь файл,если строки abc
вообще нет)H;$!d
это классический шаблон для сбора всего файла в области хранения (обратите внимание, что это может быть проблемой для очень больших файлов)x
меняем буферы вместо использования g
, чтобы избежать копирования большого буфера s/\n//
удаляет неправильную новую строку в начале, созданную добавлением к пустому пространству хранения s/\(.*mno[^\n]*\n\).*/\1/
удаляет все после последнейmno
строки (или печатает весь оставшийся файл, если строки mno
нет, как запрошено ). Обратите внимание, что [^\n]
не является POSIX и будет работать только в некоторых версиях, таких как GNU sed
. Использование Raku (, ранее известного как Perl _6)
raku -e '(S:g/ <( ^.*? $$ \n )> ^^.*? abc.*? $$ // andthen S:g/ ^^.* mno.*? $$ <(.*? $)> //).put for lines.join("\n");'
Пример ввода:
1. stu vwx yza
2. uvw xyz abc
3. abc def ghi
4. def ghi jkl
5. ghi jkl mno
6. jkl mno pqr
7. mno pqr stu
8. pqr stu vwx
9. stu vwx yza
10. mno pqr stu
11. xyz xyz xyz
Пример вывода:
2. uvw xyz abc
3. abc def ghi
4. def ghi jkl
5. ghi jkl mno
6. jkl mno pqr
7. mno pqr stu
8. pqr stu vwx
9. stu vwx yza
10. mno pqr stu
Обратите внимание, выше, что Sample Output – это возврат строк со 2 -по -10 при подаче 11-строчного Sample Input. Кроме того, когда образец ввода усекается только до строк с 1 -по -10 (, то есть с mno
в последней строке ), приведенный выше код Raku по-прежнему (правильно )возвращает строки. 2 -- -10.
Спасибо @ImHere и @ChennyStar за то, что подтолкнули меня в комментариях придумать более надежное решение Raku.
Использование GNU sed
Обратите внимание, :первая строка abc не имеет mno согласно OP, поэтому мы можем использовать этот факт в приведенном ниже коде sed.
sed -e '
/abc/,$!d
/mno/{h;b;}
$!{N;s/^/\n/;D;}
x;/./d;x
' file
В этом методе мы используем режим slurp -z
для чтения всего файла в пространстве шаблонов. Затем мы удаляем до перед первой строкой, содержащей abc. После этого доберитесь до последней строки mno, используя жадность регулярного выражения.
sed -Ez '
s/abc/\x0&/
s/.*\n(.*)\x0/\1/
s/(.*mno[^\n]*\n).*/\1/
' file
Еще один способ — двухпроходный -подход. где мы записываем номера строк первая строка abc и последняя строка mno.В Если нет, то мы вписываем $ вместо него. Затем, используя эти два числа, мы создать команду sed начало,конец p
;конецq
sed -n '/abc/{=;:a;n;/mno/=;ba}' file |
sed -En '
1{h;$s/.*/$/;}
${x;G;}
s/\n(.*)/,\1p&q/p
' | sed -nf - file
Мы можем использовать perl
, чтобы проглотить файл, и тогда весь файл будет одной длинной строкой, которую мы горят с обоих концов и останавливаются, когда наши условия соблюдены.
perl -0777 -pe '
s/^.*\n// until /^.*abc/; /mno/||next;
s/.*\n$// until /mno.*$/;
' file
Вот еще способы использования редактора sed чтобы получить желаемый результат.
sed -n '
/\n/{/mno/!d;P;D;}
/abc/,$H;$!d
z;x;G;/mno/D
s/.//;s/.$//p
' file
Еще один метод, при котором мы сохраняем строки в режиме ожидания только до тех пор, пока не будет виден /mno/. В этот момент мы переворачиваем и печатаем то, что было в ожидании.
sed -n '
/abc/,$!d
/mno/!{H;ba;}
x;p;:a
${x;//P;//!p}
' file | sed 1d
Вот способ Python, использующий универсальный метод groupby модуля itertools для выполнения работы.
python3 -c 'import sys, itertools as it
ifile,start,stop = sys.argv[1:]
G,K,F = [],[],lambda x: x.find(stop)
with open(ifile) as f:
for _ in f:
if not _.find(start): continue
for t in it.groupby(f,F):
G.append(list(t[1]))
K += [t[0] > -1]
if len(K) > 1 and not K[-1]: G.pop()
print(*[e for L in G for e in L], sep="",end="")
' file "abc" "mno"