Как редактировать список сгенерированных файлов, имена которых содержат пробелы

это зависит от рабочей нагрузки, и THP в основном дает худшую производительность. Хорошая статья находится на Percona

.

6
10.07.2020, 17:35
5 ответов

Из комментариев получаю что-то похожее типа это твоя команда:

find -type f -mtime +14 -mtime -22 -iname '*.xml' | while IFS= read -f x; do xmlstarlet sel -T -t -v '//magicElement' -n "$x" | grep -q magicValue && echo "$x"; done 

Вместо конвейера в циклwhile-вы можете использовать -exec sh -c '...'для фильтрации файлов:

find -type f -mtime +14 -mtime -22 -iname '*.xml' \
  -exec sh -c 'xmlstarlet sel -T -t -v "//magicElement" "$1" | grep -q magicValue' find-sh {} \; \
  -exec vi -- {} +

Попробуйте:

Рассмотрим три файла:

.
├── a:<magicElement>magicValue</magicElement>
├── b:<magicElement>magicValue</magicElement>
└── c:<magicElement>someOtherValue</magicElement>

$ find. -type f \
  -exec sh -c 'xmlstarlet sel -T -t -v "//magicElement" "$1" | grep -q magicValue' find-sh {} \; \
  -exec echo vi -- {} +

Выход:

vi --./a./b
5
18.03.2021, 23:20

Если ваш vi поддерживает это (и, если ваш vi — это vim, он поддерживает ), вы можете использовать список быстрых исправлений. Это функция, которая сохраняет имена файлов -1 в списке с возможностью навигации. Важными командами являются :cnextи :cprev, эквивалентные :nextи :prevдля записей быстрых исправлений. Многие другие, такие как :cfile, :cfirst, :clastи :copen, также существуют.

Итак, возникает вопрос, как загрузить файлы в список быстрых исправлений? Вот несколько вариантов:

  1. Поместите имена файлов в какой-нибудь файл и используйтеvi -q <file>:список быстрых исправлений будет установлен на основе файла. Но если вы попробуете это, где файл содержит, например,
Netherlands/Purge (GDPR) 2020-01-09.txt
Netherlands/Purge (GDPR) 2020-01-27.txt
Switzerland/New mailing 2020-01-27.txt

Вы будете разочарованы. По умолчанию 'errorformat', который указывает vi, как анализировать имена файлов -из сообщений об ошибках, установлен для компиляторов C. Итак, вам понадобится

vi --cmd 'set errorformat=%f' -q <file>

Существует несколько способов создания <file>; один pipeline... >errors. Но тогда вы должны удалить файл.

Более интересным, если ваша оболочка поддерживает это, является

vi --cmd 'set errorformat=%f' -q <(pipeline)
  1. Используйте команду :cexprс функцией system():загрузите vi и выполните команды
set errorformat=%f
cexpr system('pipeline')

Это похоже на версию с командной строкой, но включает дополнительный шаг и более сложную команду.Это более полезно, если вы уже находитесь в vi, когда вам нужно установить список быстрых исправлений (, хотя в этот момент я мог бы просто сделать

:args `pipeline`

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

Примечания

  1. Часто имена файлов -сочетаются с номерами строк или столбцов, а иногда даже с сообщениями, например, от компилятора. :help quickfixдля получения дополнительной информации.

  2. Если вы часто делаете подобные вещи, вам может понравиться эта функция оболочки:

vq () {
  if (($# > 0)); then
    vim -q <("$@" 2>&1)
  else
    printf '%s\n' 'Usage: vq cmd' '' 'Use {cmd} output as quickfix list'
  fi
}

Вы предоставляете одну команду (часто grepили тому подобное )до vq, и она делает все остальное; но это работает только в том случае, если вывод команд соответствует стандартному 'errorformat'. Однако настройка 'errorformat'после загрузки списка быстрых исправлений должна работать.

1
18.03.2021, 23:20

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

find... -print0|...| xargs -0r gvim -f

find... -print0|...| xargs -0r xterm -e vim

Это работает даже через ssh.

1
18.03.2021, 23:20

Поскольку вы находитесь в Баше,

#!/bin/bash
readarray -d '' -t files < <(find path -type f -print0)
vi -- "${files[@]}"

Замените find path -type f -print0вашим фактическим конвейером.

Хотя в ваших файлах нет новых строк, поддержка таких имен файлов была добавлена ​​пользователем glenn jackman .

Чтобы использовать вкладки вместо буферов для vi, добавьте флаг -p:vi -p....


Если конвейер не требовался, можно было просто использовать опцию -exec:

find path -type f -exec vi -- {} +
8
18.03.2021, 23:20

Unfortunately this does not work when mycommand is an editor because although xargs can assemble the set of files to edit, stdin is already taken up from the pipeline and I can't see a way to run an editor in-place.

Этот способ задокументирован на странице руководства для GNU Findutilsxargs:

   -o, --open-tty
          Reopen stdin as /dev/tty in the child process  before  executing
          the  command.  This is useful if you want xargs to run an inter‐
          active application.

Чтобы можно было использовать

find. -name 'pattern' -print0 | xargs -0o vim

Однако это новая функция. Я не вижу этого в более старой системе с xargs 4.4.2; Я вижу это в Ubuntu 18, где есть xargs 4.7.0.

Сейчас у xargs, возможно, не было опции -oдесять лет назад, но подстановка процесса Bash существовала десять лет назад, и у xargsесть опция -aдля чтения из файла вместо стандартного ввода.

Таким образом, задача решается без xargs -oвот так:

xargs -0 -a <(find. -name 'pattern' -print0) vim

Поскольку xargsчитает из (то, что он считает )файлом, полученным в качестве аргумента, он оставил стандартный ввод в покое.

7
18.03.2021, 23:20

Теги

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