sh/bash에서 인덱스로 문자열을 참조하는 방법은 무엇입니까? 즉, 기본적으로 나누어져 있습니다.
파일 이름에서 5자를 제거하려고 합니다. 모든 이름의 구조는 name_nr_code입니다. 영숫자 코드 5자리를 제거하려고 합니다. name_nr_
항상 10자입니다.
비슷한 게 있나요?
for i in * ; do mv "$i" "$i"[:10] ; done
답변1
그렇게 간단합니다.
(딸꾹질)
for i in * ; do mv -- "$i" "${i:0:5}" ; done
바라보다.
그리고 의 설명고급 Bash 스크립팅 가이드(10장 변수 조작),(추가의NOTE매뉴얼의 오류를 강조하기 위한 인라인):
부분 문자열 추출
${string:position}
다음에서 하위 문자열을 추출합니다.
$string
존재하다$position
.매개변수가 "*" 또는 "@" 인 경우
$string
위치 매개변수는 에서 시작하여 추출됩니다$position
.${string:position:length}
발췌
$length
하위 문자열의 문자는 다음에서 나옵니다.$string
존재하다$position
.
NOTE매개변수 확장에 따옴표가 누락되었습니다! echo
임의의 데이터와 함께 사용하면 안 됩니다.
stringZ=abcABC123ABCabc
# 0123456789.....
# 0-based indexing.
echo ${stringZ:0} # abcABC123ABCabc
echo ${stringZ:1} # bcABC123ABCabc
echo ${stringZ:7} # 23ABCabc
echo ${stringZ:7:3} # 23A
# Three characters of substring.
# Is it possible to index from the right end of the string?
echo ${stringZ:-4} # abcABC123ABCabc
# Defaults to full string, as in ${parameter:-default}.
# However . . .
echo ${stringZ:(-4)} # Cabc
echo ${stringZ: -4} # Cabc
# Now, it works.
# Parentheses or added space "escape" the position parameter.
이것위치그리고길이매개변수는 "매개변수화"될 수 있습니다. 즉, 숫자 상수가 아닌 변수로 표시됩니다.
인수가 "*" 또는 "@" 인 경우 처음부터
$string
최대 위치 인수가 추출됩니다 .$length
$position
echo ${*:2} # Echoes second and following positional parameters.
echo ${@:2} # Same as above.
echo ${*:2:3} # Echoes three positional parameters, starting at second.
NOTE:는 expr substr
GNU 확장입니다.
expr substr $string $position $length
발췌
$length
의 문자$string
다음으로 시작됨$position
.
stringZ=abcABC123ABCabc
# 123456789......
# 1-based indexing.
echo `expr substr $stringZ 1 2` # ab
echo `expr substr $stringZ 4 3` # ABC
NOTE: 이는 echo
중복되고 신뢰성이 훨씬 낮습니다.사용 expr substr + "$string1" 1 2
.
NOTE: expr
출력이 0(또는 -0, 00...)인 경우 0이 아닌 종료 상태가 반환됩니다.
그런데. 이 책은 공식 Ubuntu 저장소에서 abs-guide
.
답변2
POSIX에서는 sh
,
"${var%?????}"
$var
마지막 5개 문자를 제거합니다 (또는 문자가 5개 미만인$var
경우 ).$var
"${var%"${var#??????????}"}"
예, 처음 10자입니다$var
."${var%_*}"
$var
(->) 끝에서 일치하는 가장 짧은 문자열을 제거합니다 ._*
$var
foo_bar_baz
foo_bar
"${var%%_*}"
: 동일하지만 가장 짧은 일치(foo_bar_baz
->foo
) 대신 가장 긴 일치입니다.- 다음을 얻으려는 경우
foo_bar_
:"${var%"${var##*_}"}"
(끝 대신 시작 부분에서 패턴을 찾는 것과 동일${var##pattern}
).${var%%pattern}
$var
그리고 zsh
:
$var[1,-6]
첫 번째 문자부터 6번째 문자부터 마지막 문자까지(마지막 5자를 제외한 모든 문자)$var[1,10]
처음 10자.
ksh
, 또는 :bash
zsh
"${var:0:10}"
: 의 처음 10자$var
또는 :bash
zsh
"${var:0:-5}"
$var
: 마지막 5자를 제외한 모든 문자(설정되었지만 5자 미만인 경우, 오류를 표시하고 스크립트를 종료합니다.$var
use 없이 설정한 경우에도 마찬가지입니다zsh
).
Bourne 호환성이 필요한 경우 sh
안정적으로 수행하기가 어렵습니다. 결과가 줄바꿈으로 끝나지 않을 것이라고 보장할 수 있다면 다음을 수행할 수 있습니다.
first_10=`expr " $var" : ' \(.{1,10\}\)'` # beware the exit status
# may be non-zero if the
# result is 0 or 0000000000
all_but_last_5=`expr " $var" : ' \(.*\).\{5\}'`
또한 길이 제한이 적용됩니다 $var
(시스템에 따라 다름).
이러한 모든 솔루션에서 $var
유효한 문자의 일부를 구성할 수 없는 바이트를 포함하면 YMMV가 됩니다.
답변3
sh
(내가 아는 한) 문자열에서 하위 문자열을 가져오는 기본 제공 방법은 없지만 bash
다음을 수행할 수 있습니다.
${i:0:10}
그러면 변수 value 의 처음 10자가 제공됩니다 i
.
일반적인 형식은 ${variable:offset:length}
.
답변4
for
첫째, 파일 이름에 루프를 사용 하지 마십시오 .
음, 이와 같은 것이 도움이 될 것입니다.
find ./ -type f | while read filename ;do
newfilename=$(echo ${filename}|cut -c 1-10)
mv ${filename} ${newfilename}
done