bash에서 문자열 인덱싱


15

sh / bash에서 색인으로 문자열을 참조하려면 어떻게해야합니까? 즉, 기본적으로 분할됩니다.

파일 이름의 5자를 제거하려고합니다. 모든 이름의 구조는 name_nr_code입니다. 5 개의 영숫자 코드 비트를 제거하려고합니다. name_nr_항상 10 자입니다.

같은 것이 있습니까?

for i in * ; do mv "$i" "$i"[:10] ; done


5
솔루션을 bash요청하는 경우 왜 태그 sh입니까?
Stéphane Chazelas

답변:


15

이렇게 간단합니다.

(세게 때리다)

for i in * ; do mv -- "$i" "${i:0:5}" ; done

짜잔

그리고 고급 Bash 스크립팅 안내서 ( 10 장. 변수 조작 ) 의 설명 ( NOTE이 매뉴얼의 오류를 강조하기 위해 추가 인라인이 있음) :

부분 문자열 추출

${string:position}

$stringat에서 하위 문자열을 추출합니다 $position.

경우 $string매개 변수가 "*"또는 "@"입니다,이 추출물 위치 매개 변수는 시작 $position.

${string:position:length}

at에서 $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이 아닌 종료 상태로 돌아갑니다.


BTW. 이 책은 공식 우분투 저장소에로 abs-guide있습니다.


"위치"는 실제로 오프셋이기 때문에 약간 오해의 소지가 있습니다. 이는 "첫 번째 위치"에서 ${var:1}값을 반환하지 않고 var실제로는 두 번째 위치에서 값을 반환 한다는 의미입니다 .
Kusalananda

사실이지만 동의하지 않는 한 제로 순위가 될 수 있습니다. 나 한테는 괜찮아

9

POSIX에서 sh 에서는

  • "${var%?????}"$var마지막 5 개의 후행 문자 가 제거됩니다 (또는$var 경우에 $var5 개 미만의 문자가 포함)

  • "${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] 끝에서 첫 번째 문자부터 여섯 번째 문자까지 (마지막 5를 제외하고)
  • $var[1,10] 처음 10 자

ksh, bash또는zsh :

  • "${var:0:10}":의 첫 10 자 $var

bashzsh :

  • "${var:0:-5}"모든하지만 마지막 5 자 (오류를 제공하고있는 경우 스크립트를 종료 $var할 때 또한, 5 개 미만의 문자를 설정되어 있지만 포함 $var으로 설정되어 있지 않습니다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)의 일부를 구성 할 수없는 바이트가 포함 된 경우 .


내 괄호 안에는 추악한 구문이 나왔습니다.
고양이

2

sh문자열에서 하위 문자열을 가져 오는 기본 제공 방법을 제공하지는 않지만 (내가 볼 bash수있는 한)

${i:0:10}

변수 값의 처음 10자를 제공합니다. i .

일반적인 형식은 ${variable:offset:length}입니다.


2

대부분의 쉘은 당신을 도울 수있는 일종의 매개 변수 확장을 지원합니다. bash에서 사용할 수 있습니다

substr=${string:4:5} # start at position 4, length 5.

에서는 dash, 오프셋 (offset)는 지원되지 않습니다,하지만 당신은 선행 및 후행 패턴을 사용할 수 있습니다 :

remove_first3=${string#???}
remove_last2=${string%??}

0

먼저, 사용하지 마십시오 for 파일 이름에 루프를 .

그러면 이와 같은 것이 도움이 될 것입니다.

find ./ -type f | while read filename ;do
  newfilename=$(echo ${filename}|cut -c 1-10)
  mv ${filename} ${newfilename}
done

3
for파일 이름과 함께 사용 하는 것이 왜 나쁜 가요?
choroba

변수를 인용하고 printf더 안전하게 사용하십시오 . ...와 read -r.
Kusalananda

3
OP의 for루프는 누락 된 경우를 제외하고는 양호했습니다 --. 네 줄의 코드에서 적어도 10 개의 버그를 볼 수 있습니다! 파일 이름을 한 줄로 가정하고 에코, 누락 된 따옴표를 사용하는 등의 잘 알려진 나쁜 습관 중 많은 것
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.