Подтвердить что ты не робот

Как удалить префикс имени файла с помощью оболочки Posix

Как удалить префикс имени файла в Bash, как в следующем примере:

XY TD-11212239.pdf

чтобы получить

11212239.pdf

i.e, удалите XY TD-?

4b9b3361

Ответ 1

Вы указали очень мало информации, но предположив, что вы делаете это в bash, и имеете список файлов, префикс которых необходимо удалить, вы можете передать список через sed:

Например:

./generate_your_list_of_files | sed -e 's/^prefix//'

или если ваш список файлов разделен пробелами:

echo TD-file1 TD-file2.x.yt TD-file3-beep | sed -e 's/\<TD-//g'

Первый соответствует префиксу в начале строки и удаляет его. Второй соответствует TD- (или любой другой префикс, который вы хотите заменить), только когда это происходит в начале слова и заменяет его во всех совпадениях во всех строках. Это может стать опасным, например, например файл TD-file\ that\ TD-contains\ space.txt станет file\ that\ contains\ space.txt

В качестве дополнительной заметки не получите список файлов с помощью ls. Это ужасная ошибка. Если вам нужно получить список файлов для работы и ссылки в более чем одном месте, я бы предложил поместить их в массив:

files=(*)

а затем работать с этим массивом.


Из-за популярных запросов (один комментарий ниже), вот как переименовать все файлы в каталоге, начинающемся с XY TD-, чтобы префикс был удален (благодаря @tripleee):

for file in prefix*;
do
    mv "$file" "${file#XY TD-}"
done

Ответ 2

Вы сказали, что оболочки POSIX будут включать BASH, Kornshell, Ash, Zsh и Dash. К счастью, все эти оболочки имеют фильтрацию шаблонов по значениям переменных.

Шаблоны - это то, что вы используете, когда вы указываете файлы с такими вещами, как * в командной строке Unix/Linux:

$ ls *.sh  # Lists all files with a `.sh` suffix

В этих оболочках POSIX используется четыре разных фильтра:

  • ${var#pattern} - Удаляет наименьшую строку с левой стороны, которая соответствует шаблону.
  • ${var##pattern} - Удаляет большую строку с левой стороны, которая соответствует шаблону.
  • ${var%pattern} - Удаляет наименьшую строку с правой стороны, которая соответствует шаблону.
  • ${var%%pattern} - Удаляет самую большую строку с правой стороны, которая соответствует шаблону.

Вот несколько примеров:

foo="foo-bar-foobar"
echo ${foo#*-}   # echoes 'bar-foobar'  (Removes 'foo-' because that matches '*-')
echo ${foo##*-}  # echoes 'foobar' (Removes 'foo-bar-')
echo ${foo%-*}   # echoes 'foo-bar'
echo ${foo%%-*}  # echoes 'foo'

Вы действительно не объяснили, что хотите, и вы не указали какой-либо пример кода, поэтому трудно придумать что-то, что сделает то, что вы хотите. Однако, используя фильтрацию шаблонов, вы, вероятно, можете точно определить, что вы хотите делать с именами файлов.

file_name="XY TD-11212239.pdf"
mv "$file_name" "${file_name#*-}" # Removes everything from up to the first dash

Ответ 3

Вы также можете использовать инструмент переименовать

Установите его с помощью доморощенного

brew install rename

Затем запустите следующую команду из каталога, чтобы удалить "префикс-" из всех файлов

rename -d prefix- *

Ответ 4

В дополнение к извлечению подстроки, показанному в других ответах, вы также можете использовать замену подстроки. Учитывая файл:

fn="XY TD-11212239.pdf"

Тогда замена подстроки:

fn_new=${fn//*TD-/}

Будет делать то, что вы хотите.

Ответ 5

$ s='XY TD-11212239.pdf'
$ echo "${s#XY TD-}"
11212239.pdf

Если вы хотите выполнить массовое переименование:

while IFS= read -r -d '' filename; do
  mv "$filename" "${filename#XY TD-}"
done < <(find . -type f -name 'XY TD-*' -print0)

Обратите внимание, что <() является расширением bash, отсутствующим в POSIX sh. Вы можете заменить его конвейером формы find ... | while.

Аналогично, -print0 является расширением GNU, отсутствующим в поиске POSIX. Поиск POSIX не дает эквивалентного способа поиска файлов, которые безопасны для имен, содержащих новые строки, что затрудняет их замену.