Преобразование только частей имени файла в верхний регистр

Поскольку переменная не задается вашим документом:

$ VALUE=<<PERSON  
> {    
>   "type": "account",  
>   "customer_id": "1234",  
>   "customer_email": "jim@gmail.com",  
> }  
> PERSON
$ echo "$VALUE" 

$

Если вы хотите использовать heredoc для присвоения значения переменной, вам понадобится что-то вроде:

$ read -d '' -r VALUE <<PERSON  
{    
  "type": "account",  
  "customer_id": "1234",  
  "customer_email": "jim@gmail.com",  
}   
PERSON
3
16.04.2020, 16:24
3 ответа

Когда есть неясность в том, насколько далеко простирается группа, механизмы регулярных выражений сначала отдают предпочтение самому длинному совпадению. Для любого имени файла \(.*\)соответствует полному имени, а \.*.*соответствует пустой строке.

Вам понадобятся два футляра :с удлинителем или без него. Также обратите внимание, что если имя файла начинается с ., это не начало расширения.

Я не понимаю, почему вы хотите использовать expr. Управление параметрами оболочки стало проще.

При преобразовании в верхний регистр обратите внимание, что реализация trв Linux не поддерживает локали, отличные от -ASCII. Он выполняет только манипуляции с байтами. Например, echo accentué | tr a-z A-Zприводит к ACCENTUé, а не к ACCENTUÉ. Вместо этого используйте инструмент с поддержкой локали -, такой как awk. В bash вы можете использовать ${filename^^?}, но это недоступно в sh. Убедитесь, что ваш сценарий работает в правильной локали для кодировки имен файлов.

Я предполагаю, что имя файла не содержит части каталога. Если это так, сначала отделите его.

case $filename in
  ?*.*) # There is an extension
    base="${filename%.*}"; ext=".${filename##*.}";;
  *) # No extension
    base="$filename"; ext="";;
esac
upcased_base="$(printf %s. %base | awk '$0 = toupper($0)')"
upcased="${upcased_base%.}$ext"

Конечный .в %s., который затем удаляется из $upcased_base, гарантирует, что сценарий правильно обрабатывает имена файлов с новой строкой непосредственно перед расширением. Без этого подстановка команды удалит завершающие символы новой строки. Вам это не нужно, если вы уже убедились, что ваши имена файлов не содержат символов новой строки.

3
19.03.2021, 02:29

Вот полностью основанное наawk-решение, где вы должны поместить следующую строку в свой сценарий оболочки:

uppercasename="$(echo "$filename" | awk 'BEGIN{FS=OFS="."} NF==1{$1=toupper($1)} {for (i=1;i<NF;i++) $i=toupper($i)} 1')"

Это будет использовать .в качестве разделителя полей для ввода и вывода и, если найдено только одно поле, преобразовать его в верхний регистр, а во всех других случаях преобразовать все поля, кроме последних, в верхний регистр.. Затем он печатает результат (это значение 1, которое является сокращенной записью для{print}).

Если вы используете bash, вы можете избавиться от канала и указать его как

uppercasename="$(awk 'BEGIN{FS=OFS="."} NF==1{$1=toupper($1)} {for (i=1;i<NF;i++) $i=toupper($i)} 1' <<< "$filename")"

с помощью строки -.

Обратите внимание, что это разработано таким образом, что в пограничном случае имени файла, оканчивающегося на ., как в myfile.this.txt., он будет рассматривать это как «пустой, но присутствующий суффикс» и преобразовывать его в MYFILE.THIS.TXT.. Кроме того, если имя файла начинается с .и не имеет другого расширения (, как в .myfile), оно будет сохранено в нижнем регистре.

0
19.03.2021, 02:29

Если используется оболочка bash, используется только расширение параметров bash:

file="aaa.bbb.dat"

name=${file%.*} # delete everything after last dot 
ext=${file##*.} # delete everything up to last dot
upcase=${name^^*}.$ext # uppercase everything

echo "$upcase"
AAA.BBB.dat

Пробуем более сложный случай:

file="déjà vu. dat "
name=${file%.*} # delete everything after last dot 
ext=${file##*.} # delete everything up to last dot
upcase=${name^^*}.$ext # uppercase everything
echo ":$upcase:"

Дает:

:DÉJÀ VU. dat :

Так:

  • двойные кавычки не нужны, пока не будет использован результат
  • Прописные буквы подходят даже для не -символов ASCII
7
19.03.2021, 02:29

Теги

Похожие вопросы