У меня есть этот сценарий
#!/bin/bash
folder='/home/data/mnist/training'
for filePng in $folder/*
do
touch $filePng.txt
done
Это работает, просто что, для файла назвал 001.png
, это создает 001.png.txt
вместо 001.txt
.
Как я могу изменить это?
Можно использовать эти basename
команда здесь:
touch "$folder/$(basename "$filePng" .png).txt"
Примечание дополнительное $folder/
. Это необходимо, так как команда базового имени удаляет путь из.
Можно удалить существующее расширение с помощью оболочки расширение параметра функции
${parameter%pattern}
, 'шаблон' подобран против конца 'параметра'. Результатом является расширенное значение 'параметра' с самым коротким удаленным соответствием.
Так в Вашем случае, замените $filePng.txt
"${filePng%.png}.txt"
С вариацией на то, какой steeldriver, уже упомянутый - расширение параметра - мы можем использовать строковую замену, чтобы сделать задание. Кроме того, необходимо заключить переменные в кавычки. Ниже Ваш отредактированный сценарий.
#!/bin/bash
folder='/home/data/mnist/training'
for filePng in "$folder"/*
do
touch "${filePng/.png/.txt}"
done
Если Вы уверены, что у Вас нет файлов с .png
где-нибудь посреди имени, то можно просто использовать массив с расширением параметра:
pngs=( /path/to/pngs/*.png )
touch "${pngs[@]/.png/.txt}"
Это хранит все пути к файлам, заканчивающимся в .png
в массиве, и затем использует расширение параметра для создания списка .txt
файлы путем замены .png
для .txt
на каждом.
Принимают во внимание, что это повредится, если у Вас будет столько файлов, что они не могут все быть переданы как аргументы тому же вызову touch
.
Если бы Вы имеете много из файлов для создания его, стоило бы к “touch” больше чем один файл за один раз, так, чтобы Вы не должны были разветвлять новый процесс для каждого из них (который занимает некоторое время, если выполнено несколько тысяч времен).
xargs
Эта опция предоставит разнообразные пути к эти touch
команда сразу, обычно несколько тысяч или независимо от того, что система может соответствовать на единственной командной строке.
find "$folder" -mindepth 1 -maxdepth 1 -name '*.png' -print0 |
sed -ze 's/\.png$/.txt/' |
xargs -r0 -- touch --
, Эта опция не выполняет touch
вообще, но использует функции оболочки Bash/границы/POSIX вместо этого, которые не требуют подпроцессов вообще.
for f in "$folder"/*.png; do
: >> "${f%.png}.txt"
done