Bash에서 문자열 인덱싱

Bash에서 문자열 인덱싱

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 substrGNU 확장입니다.

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(->) 끝에서 일치하는 가장 짧은 문자열을 제거합니다 ._*$varfoo_bar_bazfoo_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, 또는 :bashzsh

  • "${var:0:10}": 의 처음 10자$var

또는 :bashzsh

  • "${var:0:-5}"$var: 마지막 5자를 제외한 모든 문자(설정되었지만 5자 미만인 경우, 오류를 표시하고 스크립트를 종료합니다. $varuse 없이 설정한 경우에도 마찬가지입니다 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

관련 정보