Как удалить префикс имени файла в Bash, как в следующем примере:
XY TD-11212239.pdf
чтобы получить
11212239.pdf
i.e, удалите XY TD-
?
Как удалить префикс имени файла в Bash, как в следующем примере:
XY TD-11212239.pdf
чтобы получить
11212239.pdf
i.e, удалите XY TD-
?
Вы указали очень мало информации, но предположив, что вы делаете это в 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
Вы сказали, что оболочки 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
Вы также можете использовать инструмент переименовать
Установите его с помощью доморощенного
brew install rename
Затем запустите следующую команду из каталога, чтобы удалить "префикс-" из всех файлов
rename -d prefix- *
В дополнение к извлечению подстроки, показанному в других ответах, вы также можете использовать замену подстроки. Учитывая файл:
fn="XY TD-11212239.pdf"
Тогда замена подстроки:
fn_new=${fn//*TD-/}
Будет делать то, что вы хотите.
$ 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 не дает эквивалентного способа поиска файлов, которые безопасны для имен, содержащих новые строки, что затрудняет их замену.