Как вырезать файл, начиная со строки, в которой встречается определенный шаблон?

и для рабочего стола Mate немного отличается

gsettings set org.mate.media-handling automount false

Также важно помнить, что это настройка для каждого пользователя.
Так что это действительно только для текущего пользователя рабочего стола....

сверьтесь с:

gsettings list-recursively  org.mate.media-handling

и

gsettings list-recursively  org.gnome.desktop.media-handling 

Из-за смешанного характера рабочего стола mate (я всегда использую некоторые приложения gnome )некоторые настройки gnome просачиваются в конфигурацию рабочего стола.
Поэтому я всегда устанавливаю обе части, чтобы убедиться.....

7
22.02.2020, 17:16
6 ответов

Похоже, что последовательность команд, которую вы ищете, это

/END DATA/,$d
q
.a
NEW END
.
wq

или в виде одного -вкладыша

printf '%s\n' '/END DATA/,$d' 'q' '.a' 'NEW END' '.' 'wq'

(Вы можете заменить wqна ,pдля тестирования.)

Пр. дано

$ cat file
Data 1
Data 2
something_unimportant_here END DATA
Rubbish 1
Rubbish 2

, затем

$ printf '%s\n' '/END DATA/,$d' 'q' '.a' 'NEW END' '.' 'wq' | ed -s file

дает

$ cat file
Data 1
Data 2
NEW END
6
28.04.2021, 23:22

Вы должны быть в состоянии сделать это, просто обрезав файл на месте без необходимости записи новой копии файла, как sed -i/ perl -i/ ed/ gawk -i inplace. Сperl:

find. -name '*.txt' -type f -exec perl -ne '
  BEGIN{@ARGV=map{"+<$_"}@ARGV} # open files in read+write mode in the
                                # while(<>) loop implied by -n
  if (/END DATA/) {
    seek ARGV,-length,1; # back to beginning of matching line
    print ARGV "NEW END\n";
    truncate ARGV, tell ARGV;
    close ARGV; # skip to next file
  }' {} +

Это минимизирует ввод-вывод, так как perlпрекращает чтение, как только находит совпадение, и NEW END\n— единственное, что он записывает. Он также записывается на месте, поэтому метаданные файлов (, права доступа, ACL, разреженность... )сохраняются, а жесткие ссылки не нарушаются.

С помощью -exec {} +мы также минимизируем количество perlвызовов.

8
28.04.2021, 23:22

Будьте проще и просто используйте awk для работы с файлами, например, с GNU find, awk, grep и xargs:

find. -type f -exec grep -lZ 'END DATA' {} + |
    xargs -r0 awk -i inplace '/END DATA/{nextfile} 1'

или печатать собственный закрывающий тег в конце каждого файла:

... |
  xargs -r0 awk -i inplace '/END DATA/{print "NEW END"; nextfile} 1'
3
28.04.2021, 23:22

Объединение ответа Сандипа и ответа Эда Мортона , но безxargs:

find . -type f -name '*.txt' …(other criteria)… -exec grep -q 'END DATA' {} ';'  -a  \
                                -exec sed -i -e '/END DATA/,${//i NEW END' -e 'd}' {} +
  • find, разумеется, выбирает файлы. По умолчанию он ищет указанный директор (ies )рекурсивно. Чтобы выполнить поиск только в текущем каталоге, добавьте -maxdepth 1после..
  • grep -qq автоматически завершает работу со статусом «успешно», если файл содержит искомый шаблон для(END DATA)и «false» в противном случае.
  • -aозначает «И», как и &&в командной строке оболочки. Это означает «делать следующее, если (только в том случае, если )предыдущее удалось». На самом деле, это оператор конъюнкции по умолчанию. между findпредикатами (тестами/действиями ), так что вы можете опустить это. Я включил его только для ясности.
  • Итак, команда sed,который дословно скопирован из ответа Сандипа (, но с fooизмененным на NEW END), выполняется только для файлов, содержащих строку END DATAи удовлетворяют другим findтестам.
  • -exec … +заставляет sedвызываться один раз с несколькими файлами, как это делает xargs.
    Обратите внимание, что мы не можем использовать -exec … +с командой grep. потому что это не позволяет проверить статус выхода.
1
28.04.2021, 23:22

Это pythonрешение 3.8 в общих чертах основано на решении Стефана в -местеtruncateс несколькими отличиями. 1. Код не использует внешние утилиты для обхода каталогов. 2. Файлы сопоставляются с памятью -для облегчения поиска строки END DATA

.

Поместите код в файл .pyи передайте имя каталога в качестве параметра

import mmap
import os
import sys
from contextlib import closing

def yield_all_files(dir_):
    for root, dir_, files in os.walk(dir_):
        yield from (os.path.join(root, file_) for file_ in files if file_.endswith('.txt'))

if __name__ == '__main__':
    old = b'END DATA'
    new = b'NEW END\n'
    dir_ = sys.argv[1]
    for file_ in yield_all_files(dir_):
        with open(file_, mode='r+b') as f:
            with closing(mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_WRITE)) as mm:
                if (loc := mm.find(old)) > -1:
                    mm.seek(loc)
                    mm.write(new)
                    mm.resize(mm.tell()) 
2
28.04.2021, 23:22

Использование awk для поиска смещения шаблона и ddдля усечения файла в этой точке и добавления нового трейлера:

# usage truncatoo pattern new_end find_args...
truncatoo(){
    pat=$1; shift; tail=$1; shift
    LC_CTYPE=C TAIL=$tail find "$@" -exec awk -v q="'" "$pat"'{
           gsub(q,q"\\"q q,FILENAME);
           system("printf \"$TAIL\" | dd bs="l" seek=1 of="q FILENAME q" 2>/dev/null");
           exit
       }
       {l+=length()+1}
    ' {} \;
}

truncatoo '/END DATA/' 'NEW END\n' file.txt
truncatoo '/END DATA/' 'NEW END\n'. -type f -name '*.txt'

С реализацией awk, которая поддерживает nextfile(gawk, bwk, некоторые версии mawk[1] ), это можно сделать более эффективно, передавая пакеты файлов в awk:

# usage truncatoo pattern new_end find_args...
truncatoo(){
    pat=$1; shift; tail=$1; shift
    LC_CTYPE=C TAIL=$tail find "$@" -exec awk -v q="'" "$pat"'{
           gsub(q,q"\\"q q,FILENAME);
           system("printf \"$TAIL\" | dd bs="l" seek=1 of="q FILENAME q" 2>/dev/null");
           l=0; nextfile
       }
       {l+=length()+1}
    ' {} +
}
$ file="a'b\$q  * r"; seq 1 100 >"$file"
$ truncatoo /7/ 'CUT\n' "$file"; cat "$file"
1
2
3
4
5
6
CUT

Вместо icky2>/dev/nullstatus=noxferможно использовать с ddреализациями, которые его поддерживают.

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

[1] :в соответствии с руководством GNU awk , он также должен поддерживаться в mawk. Однако старая версия mawk из Debian 10 его не поддерживает.

0
28.04.2021, 23:22

Теги

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