Переписывание файлов, найденных поиском?

У меня есть список файлов

-rw-rw-r-- 1 tt 24813 Oct 23 2002 fig8_21.gif -rw-rw-r-- 1 tt 2259 Oct 23 2002 fig8_21t.gif -rw-rw-r-- 1 tt 35331 Oct 23 2002 fig8_23.gif -rw-rw-r-- 1 tt 2610 Oct 23 2002 fig8_23t.gif -rw-rw-r-- 1 tt 19970 Oct 23 2002 fig8_24.gif -rw-rw-r-- 1 tt 2019 Oct 23 2002 fig8_24t.gif -rw-rw-r-- 1 tt 54623 Oct 23 2002 fig8_3.gif -rw-rw-r-- 1 tt 3657 Oct 23 2002 fig8_3t.gif -rw-rw-r-- 1 tt 35861 Oct 23 2002 fig8_4.gif -rw-rw-r-- 1 tt 2344 Oct 23 2002 fig8_4t.gif 

Я хочу перезаписать <...>t.gif с помощью <...>.gif fig8_4.gif например, скопировать fig8_4.gif чтобы перезаписать fig8_4t.gif .

  • Как я могу настроить переименование подкастов после их загрузки с помощью gPodder?
  • Найти каталоги и файлы с разрешениями, отличными от 775/664
  • find утилита не распознает скобки
  • Найти файлы не в белом списке регулярных выражений
  • Найти и создать пустые файлы с тем же именем в другом месте
  • Как фильтровать файлы с именем файла, а затем удалять файл OLDEST?
  • Сначала я нахожу те <...>t.gif файлы по find . -regex ".*t\.gif" find . -regex ".*t\.gif" . Затем я хочу использовать basename для basename имен файлов, но почему у меня есть следующие предупреждения?

     $ find . -regex ".*t\.gif" -execdir basename {} \; find: The relative path `~/program_files/internet/SSH_tunneling/' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH $ find . -regex ".*t\.gif" | xargs basename basename: extra operand './f10_1t.gif' 

    Как продолжить выполнение моей задачи?

    Можно ли не использовать find ?

  • Перемещение файлов с помощью find + xargs: target не является каталогом?
  • Найти файлы с групповыми разрешениями более ограничительными, чем разрешения владельца
  • отсутствующий аргумент для поиска -exec
  • Зацикливание файлов с пробелами в именах?
  • Найти тип файла reverse
  • производительность в отношении запросов «найти» аргументы
  • 4 Solutions collect form web for “Переписывание файлов, найденных поиском?”

    Да, это возможно. Один из способов сделать это может выглядеть так:

     cd /den/of/gifs && \ for f in ./*t.gif; do mv -- "${f%%t.gif}.gif" "$f" done 

    Элемент ${var%%pattern} является стандартным / POSIX sh синтаксисом для удаления самой длинной строки, которая соответствует шаблону с конца $var .

    Чтобы сделать его еще более компактным и быстрым, вы можете использовать parallel :

     parallel mv {} {.}t.gif :::: <(find . -regex '.+[0-9].gif') 

    Выражение после :::: содержит аргументы для parallel . Эти аргументы затем используются с помощью {} . Параметр {.} Представляет аргумент без расширения файла. Итак, в нашем случае {} будут имена файлов файлов без t в них, например fig8_4.gif . {.} тогда будет fig8_4 .

    Если вы хотите остаться с find и basename , это должно работать:

     find . -name "*.gif" ! -name "*t.gif" -execdir sh -c ' cp -- "$0" "$(basename "$0" .gif)t.gif"' {} \; 

    Это эффективный и ресурсосберегающий не лучший вариант.

    О ваших ошибках:

    find: относительный путь `~ / program_files / internet / SSH_tunneling / 'включен в переменную среды PATH, которая небезопасна в сочетании с действием -execdir find. Удалите эту запись из $ PATH

    У вас есть ~/program_files/internet/SSH_tunneling/ в вашей $PATH . Это буквально ~ . Это не означает ваш домашний каталог . Вместо этого это означает относительный путь ~/program_files/internet/SSH_tunneling/ , то есть SSH_tunneling внутри internet внутри program_files внутри каталога ~ внутри текущего каталога.

    -execdir не любит относительные каталоги в $PATH потому что он делает chdir() в каталогах, на которых запускаются команды для выполнения. Например, если при ./some-dir дерева каталогов find gif файл в ./some-dir который также содержит каталог ~ , и есть ./some-dir/~/program_files/internet/SSH_tunneling/basename , то это может завершите выполнение этого basename .

    Вероятно, у вас есть:

     PATH="~/program_files/internet/SSH_tunneling/" 

    в вашем ~/.bash* который должен был быть:

     PATH=~/program_files/internet/SSH_tunneling/ 

    или

     PATH="$HOME/program_files/internet/SSH_tunneling" 
      $ find . -regex ".*t\.gif" | xargs basename basename: extra operand './f10_1t.gif' 

    xargs будет запускать basename с максимально возможным количеством аргументов. basename ожидает не более 2 аргументов, первый – путь, второй – шаблон. Поэтому ваша команда не имеет смысла.

    Также по умолчанию xargs ожидает пустой пробел (пробел, табуляция и, возможно, больше в зависимости от вашей локали и реализации find ) и новую строку (все из которых могут встречаться в именах файлов), на вкладке со специальной обработкой кавычек, которая не является формат вывода путем find .

    find выведет что-то вроде:

     ./path/to/picture from "The End of the World".gif 

    Какие xargs будут понимать как 3 разных аргумента: ./path/to/picture , from , The End of the World.gif . find не имеет режима вывода в формате, ожидаемом xargs , здесь:

     ./path/to/picture\ from\ \"The\ End\ of\ the\ World\".gif 

    или

     './path/to/picture from "The End of the World".gif' 

    Некоторые реализации xargs поддерживают опцию -0 хотя для обработки списка с разделителями NUL вместо «blank / newline +» кавычки один, а некоторые реализации find имеют предикат -print0 для вывода имен файлов в этом формате (на тех, которые этого не делают, вы можете используйте -exec printf '%s\0' {} + вместо).

    Итак, что-то вроде:

     find . -name "*t.gif" -print0 | xargs -r0 -I {} basename {} t.gif 

    что было бы малопригодным для вашей общей цели. Вместо этого вы, вероятно, хотите что-то вроде:

     find . -name '*t.gif' -type f -exec sh -c ' for f do cp "${f%t.gif}.gif" "$f" done' sh {} + 

    Или с zsh :

     autoload zmv # if not already in ~/.zshrc zmv -C '(**/)(*)t.gif(#qD.)' '$1$2.gif' 
    Linux и Unix - лучшая ОС в мире.