쉘 스크립트에서는 변환된 파일 이름이 아직 존재하지 않는 경우 파일 이름을 대문자로 변환해야 합니다. 이 특별한 경우에는 기본 이름을 대문자로 변경하고 확장자(있는 경우)는 변경하지 않았습니다.
이 문제를 해결하기 위한 저의 생각은 먼저 기본 이름과 확장자를 별도로 추출하고
tr
명령을 사용하여 기본 이름을 대문자로 변환한 다음 변경된 기본 이름과 확장자가 디렉터리에 있는지 확인하는 것입니다.
존재하지 않으면 mv를 사용하여 원래 파일 이름을 대문자 기본 이름으로 변경합니다. 이제 이 작업은 두 가지 방법으로 수행할 수 있다고 생각합니다. 첫 번째는 을 사용 expr
하고 두 번째는 cut
with .
(space-period-space)를 구분 기호로 사용하는 것입니다.
기본 이름을 추출하는 데 사용하려면 expr
(예: 파일 이름 - python1.py
또는 phonelist
) 다음과 같이 작성했습니다.
basefile=`expr "$filename" : '\(.*\)\.*.*' `
또한 0개 이상의 항목이 무시되므로 \.*
확장자 없이 해당 파일 이름을 사용했지만 이 표현식은 작동하지 않았습니다. 모든 파일 이름에 대해 전체 파일 이름을 있는 그대로 반환합니다.\.*
.
expr
누구든지 내가 어디로 잘못 가고 있는지 설명 할 수 있습니까? 또한 expr
파일 이름에서만 확장자를 추출하는 방법도 제안해 주세요 .
답변1
쉘이 이면 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가 아닌 문자에도 대문자가 작동하는 것 같습니다.
답변2
그룹이 얼마나 확장되는지 모호한 경우 정규식 엔진은 가장 긴 일치 항목부터 우선 순위를 정합니다. 모든 파일 이름에 대해 \(.*\)
전체 이름과 일치하고 \.*.*
빈 문자열과 일치합니다.
확장 여부에 관계없이 두 가지가 모두 필요합니다. 또한 파일 이름이 로 시작하는 경우 .
이는 확장자의 시작이 아닙니다.
expr
왜 .Shell 매개변수 조작을 사용하여 더 쉽게 만들고 싶은지 이해할 수 없습니다 .
대문자로 변환할 때 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
이것은 완전한 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
소문자로 유지됩니다.