Это хорошая привычка заключать в кавычки ваши переменные. Сценарий оболочки - это странный язык, который эволюционировал с течением времени, а не был идеально разработан с самого начала, поэтому, к сожалению, некоторые раздражающие вещи, подобные этой, становятся необходимыми. Без кавычек ваших переменных, пробелы или звездочки в содержимом переменных приведут к странным путям. Чтобы сделать ваши сценарии более надежными, всегда окружайте использование ваших переменных двойными кавычками. Здесь вы можете сказать for filePng in "$folder"/*и touch "$filePng".txt - обратите внимание, что вы цитируете их только тогда, когда им предшествует $.
Музер
3
Это похоже на проблему XY ... Почему вы пытаетесь это сделать?
JeromeJ
Ответы:
16
Вы можете использовать basenameкоманду здесь:
touch "$folder/$(basename "$filePng" .png).txt"
Обратите внимание на дополнительное $folder/. Это необходимо, поскольку команда basename удаляет путь из.
Могу ли я предположить, что вы процитировали расширение параметров и подстановку команд?
Том Фенек
@ TomFenech да, наверное, хорошая идея процитировать всю строку. Я отредактировал свой ответ.
Wayne_Yux
Я не уверен, почему вы удалили внутренние кавычки $filePng- они тоже были полезны.
Том Фенек,
1
Нет, потому что $( )устанавливает новый контекст цитирования.
Том Фенек
2
О, ты прав - узнал что-то новое сегодня ;-)
Wayne_Yux
31
Вы можете удалить существующее расширение, используя функции расширения параметров оболочки
${parameter%pattern}«Шаблон» сопоставляется с концом «параметра». Результатом является расширенное значение параметра с удалением кратчайшего соответствия.
Так что в вашем случае замените $filePng.txtна"${filePng%.png}.txt"
В зависимости от того, что уже упоминалось в Steeldriver - расширение параметров - мы можем использовать замену строк для выполнения этой работы. Кроме того, вы должны заключать в кавычки переменные. Ниже ваш отредактированный скрипт.
Если у вас есть много файлов для создания, было бы целесообразно «дотронуться» более чем до одного файла за раз, чтобы вам не нужно было форкировать новый процесс для каждого из них (который занимает довольно много времени, если выполняется несколько тысячу раз).
Вариант 1: замена шаблона + xargs
Эта опция будет предоставлять несколько путей к touchкоманде одновременно, обычно несколько тысяч или что угодно, что система может поместиться в одной командной строке.
Это сохраняет все пути к файлам , заканчивающихся .pngв массиве , а затем использует параметр расширения для создания списка .txtфайлов, путем замены .pngна .txtна каждом из них.
Имейте в виду, что это сломается, если у вас будет так много файлов, что все они не могут быть переданы в качестве аргументов для одного и того же вызова touch.
for filePng in "$folder"/*
иtouch "$filePng".txt
- обратите внимание, что вы цитируете их только тогда, когда им предшествует$
.Ответы:
Вы можете использовать
basename
команду здесь:Обратите внимание на дополнительное
$folder/
. Это необходимо, поскольку команда basename удаляет путь из.источник
$filePng
- они тоже были полезны.$( )
устанавливает новый контекст цитирования.Вы можете удалить существующее расширение, используя функции расширения параметров оболочки
Так что в вашем случае замените
$filePng.txt
на"${filePng%.png}.txt"
источник
В зависимости от того, что уже упоминалось в Steeldriver - расширение параметров - мы можем использовать замену строк для выполнения этой работы. Кроме того, вы должны заключать в кавычки переменные. Ниже ваш отредактированный скрипт.
источник
Если у вас есть много файлов для создания, было бы целесообразно «дотронуться» более чем до одного файла за раз, чтобы вам не нужно было форкировать новый процесс для каждого из них (который занимает довольно много времени, если выполняется несколько тысячу раз).
Вариант 1: замена шаблона +
xargs
Эта опция будет предоставлять несколько путей к
touch
команде одновременно, обычно несколько тысяч или что угодно, что система может поместиться в одной командной строке.Вариант 2: расширение параметра + перенаправление вывода команды
Эта опция вообще не запускается,
touch
а использует функции оболочки Bash / Bourne / POSIX, которые вообще не требуют подпроцессов.источник
Если вы уверены, что у вас нет файлов с
.png
серединой имени, вы можете просто использовать массив с расширением параметров:Это сохраняет все пути к файлам , заканчивающихся
.png
в массиве , а затем использует параметр расширения для создания списка.txt
файлов, путем замены.png
на.txt
на каждом из них.Имейте в виду, что это сломается, если у вас будет так много файлов, что все они не могут быть переданы в качестве аргументов для одного и того же вызова
touch
.источник