문제
주어진 파일 이름에서 양식 someletters_12345_moreleters.ext
, 고 싶을 추출하는 5 자리하는 변수입니다.
그래서 요점을 강조하고,나는 파일 이름으로 x 문자 수를 다섯 숫자는 순서에 의해 둘러싸여 하나의 밑줄 양쪽에서 다음 또 다른 호의의 숫자를 자입니다.를 가지고 싶 5 자리 숫자는 변수가 있습니다.
나는 매우의 수에 관심이 있는 다른 방법이 수행할 수 있습니다.
해결책
사 절단:
echo 'someletters_12345_moreleters.ext' | cut -d'_' -f 2
더 일반적인:
INPUT='someletters_12345_moreleters.ext'
SUBSTRING=$(echo $INPUT| cut -d'_' -f 2)
echo $SUBSTRING
다른 팁
는 경우 x 은 일정한 다음 매개 변수는 확장을 수행 하위 문자열 추출:
b=${a:12:5}
가 12 은 오프셋(zero 기반)및 5 길이
면 밑줄 주위에 자리 숫자만 입력할 수 있습거와 접미사(각각)에서 두 단계:
tmp=${a#*_} # remove prefix ending in "_"
b=${tmp%_*} # remove suffix starting with "_"
이 있는 경우 다른 밑줄 그것은 아마도 가능한 어쨌든,이기는 하지만 더 까다 롭습니다.누구나 알고있는 경우를 수행하는 방법을 모두 확장을 단일 식에서,나는 알고 싶어 너무입니다.
모두 솔루션을 제시하는 순수한 bash 없이,프로세스 산란이 참여,따라서 매우 빠르다.
일반 솔루션이는 숫자가 될 수 있습니다 어디에서 파일명을 사용하여,최초의 그러한 시퀀스:
number=$(echo $filename | egrep -o '[[:digit:]]{5}' | head -n1)
다른 솔루션을 추출물이 정확히 일부분의 변:
number=${filename:offset:length}
는 경우에 당신의 이름을 항상 형식 stuff_digits_...
당신이 사용할 수 있습 awk:
number=$(echo $filename | awk -F _ '{ print $2 }')
아직 다른 솔루션을 제거를 제외한 모든 숫자,사용
number=$(echo $filename | tr -cd '[[:digit:]]')
그냥을 사용하려고 cut -c startIndx-stopIndx
경우에 누군가가 원하는 더 엄격한 정보를 검색할 수도 있습니다 그것은 사람 bash 다음과 같이
$ man bash [press return key]
/substring [press return key]
[press "n" key]
[press "n" key]
[press "n" key]
[press "n" key]
결과:
${parameter:offset} ${parameter:offset:length} Substring Expansion. Expands to up to length characters of parameter starting at the character specified by offset. If length is omitted, expands to the substring of parameter start‐ ing at the character specified by offset. length and offset are arithmetic expressions (see ARITHMETIC EVALUATION below). If offset evaluates to a number less than zero, the value is used as an offset from the end of the value of parameter. Arithmetic expressions starting with a - must be separated by whitespace from the preceding : to be distinguished from the Use Default Values expansion. If length evaluates to a number less than zero, and parameter is not @ and not an indexed or associative array, it is interpreted as an offset from the end of the value of parameter rather than a number of characters, and the expan‐ sion is the characters between the two offsets. If parameter is @, the result is length positional parameters beginning at off‐ set. If parameter is an indexed array name subscripted by @ or *, the result is the length members of the array beginning with ${parameter[offset]}. A negative offset is taken relative to one greater than the maximum index of the specified array. Sub‐ string expansion applied to an associative array produces unde‐ fined results. Note that a negative offset must be separated from the colon by at least one space to avoid being confused with the :- expansion. Substring indexing is zero-based unless the positional parameters are used, in which case the indexing starts at 1 by default. If offset is 0, and the positional parameters are used, $0 is prefixed to the list.
건물에서 조의 답변(는 작동하지 않게):
substring=$(expr "$filename" : '.*_\([^_]*\)_.*')
놀랐어요 이 순수한 bash 솔루션이 떠오르지 않았:
a="someletters_12345_moreleters.ext"
IFS="_"
set $a
echo $2
# prints 12345
당신은 아마를 재설정하려 IFS 무엇을 값기 전에,또는 unset IFS
그 후!
다음과 같은 요구사항
나는 파일이름을 가진 x 문자 수를 다섯 숫자 순서에 의해 둘러싸여 하나의 밑줄 양쪽에서 다음 또 다른 설정의 x 수 문자입니다.를 가지고 싶 5 자리 숫자와 는 변수가 있습니다.
나는 몇 가지를 발견 grep
는 방법이 유용할 수 있습니다:
$ echo "someletters_12345_moreleters.ext" | grep -Eo "[[:digit:]]+"
12345
또는 더 나은
$ echo "someletters_12345_moreleters.ext" | grep -Eo "[[:digit:]]{5}"
12345
다음 -Po
syntax:
$ echo "someletters_12345_moreleters.ext" | grep -Po '(?<=_)\d+'
12345
는 경우 또는 당신이 그것을 만들고 싶어 정확히 맞 5 자:
$ echo "someletters_12345_moreleters.ext" | grep -Po '(?<=_)\d{5}'
12345
마지막으로,그것을 저장할 변수에 그것은 단지 사용할 필요가 var=$(command)
문입니다.
여기에 어떻게 할 겁:
FN=someletters_12345_moreleters.ext
[[ ${FN} =~ _([[:digit:]]{5})_ ]] && NUM=${BASH_REMATCH[1]}
참고:위의 정규표현식을 제한하는 특정 시나리오의 다섯 숫자에 의해 둘러싸여 주십시오.변경 정규식이 필요한 경우 다른 일치합니다.
없이 모든 하위스 프로세스 할 수 있습니다:
shopt -s extglob
front=${input%%_+([a-zA-Z]).*}
digits=${front##+([a-zA-Z])_}
아주 작은 변종의 것입니다 또한 작업에서 ksh93.
는 경우 우리의 개념에서:
"의 실행(중 하나 또는 여러)숫자"
우리가 사용할 수 있는 여러 가지는 외부 도구를 추출하는 숫자입니다.
우리는 아주 중 erase 기타 모든 문자,또 sed 또는 tr:
name='someletters_12345_moreleters.ext'
echo $name | sed 's/[^0-9]*//g' # 12345
echo $name | tr -c -d 0-9 # 12345
만$이름이 들어 여행의 숫자,위의 실패할 것이다:
는 경우"name=someletters_12345_moreleters_323_end.ext":다음
echo $name | sed 's/[^0-9]*//g' # 12345323
echo $name | tr -c -d 0-9 # 12345323
우리가 사용할 필요가정을 변경하고 싶을지도 모릅(regex).
선택하려면 첫 번째 실행(12345 지 323)sed 및 perl:
echo $name | sed 's/[^0-9]*\([0-9]\{1,\}\).*$/\1/'
perl -e 'my $name='$name';my ($num)=$name=~/(\d+)/;print "$num\n";'
하지만 우리가 할 수뿐만 아니라 그것을 직접 bash(1) :
regex=[^0-9]*([0-9]{1,}).*$; \
[[ $name =~ $regex ]] && echo ${BASH_REMATCH[1]}
이것은 우리를 추출하는 첫 번째 실행의 자리 숫자의 모든 길이
에 의해 둘러싸여 다른 텍스트/자입니다.
참고: regex=[^0-9]*([0-9]{5,5}).*$;
만 일치하는 정확히 5 자리를 실행합니다.:-)
(1):호출하는 것보다 더 빠른 외부 도구를 위한 각각의 짧은 텍스트.지보다 더 빨리 모든 일을 처리 내부에 sed 또는 awk 에 대한 큰 파일이 있습니다.
여기에는 접두사-접미사 솔루션(와 유사한 솔루션을 제공 JB 및 Darron)과 일치하는 첫 번째 블록의 자리에 의존하지 않는 주변의 밑줄:
str='someletters_12345_morele34ters.ext'
s1="${str#"${str%%[[:digit:]]*}"}" # strip off non-digit prefix from str
s2="${s1%%[^[:digit:]]*}" # strip off non-digit suffix from s1
echo "$s2" # 12345
내가 사랑 sed
아 처리하는 기능을 가진 regex 그룹:
> var="someletters_12345_moreletters.ext"
> digits=$( echo $var | sed "s/.*_\([0-9]\+\).*/\1/p" -n )
> echo $digits
12345
약간 더 일반적인 옵션 지 의 가치를 밑줄 _
의 시작을 표 시하는 귀하의 자리 숫자 시퀀스,따라서 예를 들면 벗기는 모든 비 번호는 당신을 얻을 하기 전에 당신의 순서: s/[^0-9]\+\([0-9]\+\).*/\1/p
.
> man sed | grep s/regexp/replacement -A 2
s/regexp/replacement/
Attempt to match regexp against the pattern space. If successful, replace that portion matched with replacement. The replacement may contain the special character & to
refer to that portion of the pattern space which matched, and the special escapes \1 through \9 to refer to the corresponding matching sub-expressions in the regexp.
에 더 이 경우에,당신은 너무와 자신감 regexps:
s
은 _s_ubstitute[0-9]+
경기 1+숫자\1
링크 그룹 n.1 의 regex 출력(그룹 0 은 전체 경기,그룹이 1 경기,괄호 안에서 이 경우)p
깃발을 위한 _p_rinting
모든 escapes \
이 sed
's regexp 처리 작동합니다.
어 test.txt 는 파일을 포함하는"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
cut -b19-20 test.txt > test1.txt # This will extract chars 19 & 20 "ST"
while read -r; do;
> x=$REPLY
> done < test1.txt
echo $x
ST
내 대답이 있을 것이 더 제어에 당신이 무엇을 원하는 귀하의 문자열입니다.여기에는 코드에서 어떻게 추출할 수 있습니다 12345
귀하의 문자열
str="someletters_12345_moreleters.ext"
str=${str#*_}
str=${str%_more*}
echo $str
이것이 더 효율적인을 추출하고 싶은 경우에 뭔가가 있는 어떤 문자처럼 abc
또 어떤 와 같은 특수 문자를 사용하여 _
나 -
.예를 들어:는 경우에 귀하의 문자열은 다음과 같이하고 당신이 원하는 모든 것을 후 someletters_
기 _moreleters.ext
:
str="someletters_123-45-24a&13b-1_moreleters.ext"
나의 코드를 말할 수 있는 정확히 무엇을 원합니다.설명:
#*
그것이 제거됩니다 앞의 문자열을 포함하여 일치하는 키입니다.여기서 키를 우리가 언급은 _
%
그것이 제거됩니다 다음 문자열을 포함하여 일치하는 키입니다.여기서 키를 우리가 언급은'_more*'
일부 실험 자신을 찾을 것이 흥미롭습니다.
비슷한 substr('다.',2-1,3)php:
echo 'abcdefg'|tail -c +2|head -c 3
확인,여기가 순수한 매개 변수를 대체과 빈 문자열입니다.주의해야 할 점은 내가 정의 someletters 고 moreletters 으로만 문자입니다.면 그들은 영숫자,이 것이 그것으로 작동하지 않습니다.
filename=someletters_12345_moreletters.ext
substring=${filename//@(+([a-z])_|_+([a-z]).*)}
echo $substring
12345
또한 bash 내장'expr'명령:
INPUT="someletters_12345_moreleters.ext"
SUBSTRING=`expr match "$INPUT" '.*_\([[:digit:]]*\)_.*' `
echo $SUBSTRING
조금 늦었지만,나는 이 문제를 찾은 다음과 같다:
host:/tmp$ asd=someletters_12345_moreleters.ext
host:/tmp$ echo `expr $asd : '.*_\(.*\)_'`
12345
host:/tmp$
내가 사용하는 그것을 얻을 밀리초 해상도에서는 임베디드 시스템에 있지 않%N 날짜:
set `grep "now at" /proc/timer_list`
nano=$3
fraction=`expr $nano : '.*\(...\)......'`
$debug nano is $nano, fraction is $fraction
Bash 솔루션:
IFS="_" read -r x digs x <<<'someletters_12345_moreleters.ext'
이 소지품 라는 변수 x
.Var x
변경될 수 있습 var _
.
input='someletters_12345_moreleters.ext'
IFS="_" read -r _ digs _ <<<"$input"