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

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

<code>XY TD-11212239.pdf
</code>

получить

<code>11212239.pdf
</code>

т.е. удалитьXY TD-?

 ArjunShankar10 мая 2012 г., 16:35
@hamid - Хотите переименовать файлы, удалив префикс? Вы хотите сделать это в оболочке, например, в bash или в программе (на каком языке?)?
 ArjunShankar10 мая 2012 г., 16:32
@ Shahbaz: Хм .. Но ОП говорит, чтоXY TD- «префикс имени файла», который он хочет удалить. Тогда «XY» не может быть командой оболочки.
 ArjunShankar10 мая 2012 г., 16:20
Linux - это ядро. Вы на самом деле имеете в виду [bash] или [sh] (или другую оболочку) вместо этого?
 ArjunShankar10 мая 2012 г., 16:27
Редактирование @ Shahbaz: хотя ОП, вероятно, означало «оболочку», на самом деле это можно сделать, например, написав программу на Си. Я имею в виду следующее: лучше позволить ОП уточнить, имел ли он в виду «оболочка».
 Shahbaz10 мая 2012 г., 16:29
@ArjunShankar, я удалил оболочку из заголовка, но, кстати, он выполняет команду (XY file-nameЯ до сих пор считаю, что он хочет сделать это в оболочке.

Ответы на вопрос(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 find. POSIX find не предоставляет эквивалентного способа поиска файлов, который безопасен для имен, содержащих символы новой строки, что затрудняет его замену.

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

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

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

Эти оболочки POSIX используют четыре разных шаблона фильтрации:

${var#pattern} - Removes smallest string from the left side that matches the pattern. ${var##pattern} - Removes the largest string from the left side that matches the pattern. ${var%pattern} - Removes the smallest string from the right side that matches the pattern. ${var%%pattern} - Removes the largest string from the right side that matches the 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

Вы дали очень мало информации, но, предполагая, что вы делаете это в 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- (или любой другой префикс, который вы хотите заменить) только тогда, когда это происходит в начале слова и заменяет его во всех совпадениях во всех строках. этоcould опасно, хотя, например, файл, как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
 10 мая 2012 г., 16:58
@tripleee, это волшебство!
 10 мая 2012 г., 16:56
@tripleee, спасибо, что сообщили мне об этом. На самом деле, я только недавно изучал скриптовый язык bash. Я обновил свой ответ.
 10 мая 2012 г., 16:35
@ArjunShankar, см. Мое редактирование.
 10 мая 2012 г., 16:28
Также возможно, что OP хочет «переименовать»; оригинальные файлы. Вопросы действительно слишком расплывчаты, чтобы на них было достаточно ответов.
 10 мая 2012 г., 16:56
... и за оперативность и правильность,mv "$file" "${file#XY\ TD-}" с правильным цитированием и встроенным в оболочку механизмом замены.

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

fn="XY TD-11212239.pdf"

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

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

Также буду делать что хочешь.

 03 апр. 2015 г., 00:30
Это спасло мое здравомыслие сегодня. Благодарю.

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

Установите его с домашним пивом

brew install rename

Затем выполните указанную ниже команду из каталога, чтобы удалить префикс & quot; из всех файлов

rename -d prefix- *

 27 авг. 2014 г., 22:01
Хороший мощныйperl инструмент!

Ваш ответ на вопрос