bash에서 문자열의 단어 색인을 찾는 방법은 무엇입니까?


10

bash 스크립트에서

하나 이상의 공백으로 구분 된 여러 단어가 포함 된 문자열이 있습니다. 즉 :

Name   Age Sex  ID         Address

예를 들어 단어 "나이"의 색인을 찾으려면 단어를 찾으려면 어떻게해야합니까?

원하는 단어의 색인 번호를 직접 반환하는 명령이 있습니까?

감사.


솔루션이 엄격하게 bash에 있어야합니까? 아니면 awk, grep 등을 사용할 수 있습니까?
jftuga

답변:


12

Bash 는 문자열 자체에서 단어 분리 를 수행합니다 . 실제로 문제를 피하고 인용이 그렇게 중요한 이유를 피하는 것이 아닙니다. 따옴표를 사용하지 않고 문자열을 배열에 넣으면 bash는 단어 분리를 사용하여 개별 요소를 구분합니다. 문자열이 변수에 저장되어 있다고 가정하면 $str,

ar=($str) # no quotes!

5 요소의 배열을 반환합니다. 배열 인덱스는 단어 인덱스 (대부분의 스크립팅 및 프로그래밍 언어에서와 같이 0부터 시작)입니다. 즉, "나이"는

${ar[1]}  # 0 => Name, 1 => Age, 2 => Sex, 3 => ID, 4 => Address

또는 컨텐츠별로 요소 인덱스를 찾아야하는 경우 배열을 반복합니다. 즉

function el_index {
    cnt=0; for el in "${ar[@]}"; do
        [[ $el == "$1" ]] && echo $cnt && break
        ((++cnt))
    done
}
el_index "Age" # => 1

와우 ... 나는 따옴표가 없으면 배열이 될 줄 몰랐습니다. 감사!
G3Y

4
$ export FOO="Name   Age Sex  ID         Address"

* 연령을 연령으로 대체- "연령"이전의 모든 항목을 제거합니다.

$ echo ${FOO/*Age/Age}
Age Sex ID Address

"나이"전에 무엇이든 가져 오기

$ echo ${FOO/Age*/}
Name

해당 문자열의 길이 ( "Age"의 색인)를 가져옵니다.

$ BEGIN=${FOO/Age*/}
$ echo ${#BEGIN}
7

질문에 대답하지 않지만 와우! 매끄러운 트릭. 심지어 재에서 작동하며 내장 변수가 있습니다 : export L='debug info warn error'; export GTE='warn'; echo ${L/*${GTE}/${GTE}}'warn error'를 출력합니다
Steve Tarver

0

bash를 엄격하게 사용할 필요는 없지만 bash가있는 시스템에서 일반적으로 사용되는 다른 프로그램을 사용할 수 있다면 다음과 같은 것을 사용할 수 있습니다.

echo "Name   Age Sex ID  Addr" | python -c 'print(raw_input().index("Age"))+1'

파이썬은 문자열 색인을 0에서 시작하므로 명령 끝에 +1을 추가했습니다.


0

bash의 네이티브 정규식을 사용할 수 있습니다

# a function to print the index of a field and its name
printIx() { 
  for ((l=0,i=1;i<$1;i++)) ;do 
     ((l+=${#BASH_REMATCH[i]}))
  done
  printf '%3s %s\n' $l "$2"
}

#   Using a zero based index
#   "0----+----1----+----2----+----3----+----4"
str="  Name   Age Sex  ID         Address   "

if [[ $str =~ ^(\ *)(Name)(\ +)(Age)(\ +)(Sex)(\ +()ID)(\ +)(Address)\ *$ ]] ;then
  F=(Name Age Sex ID Address)
  f=(   2   4   6  8      10)  # regex back-references
  for ((g=0;g<${#f[@]};g++)) ;do
     printIx  ${f[g]} "${F[g]}"
  done 
fi

산출

  2 Name
  9 Age
 13 Sex
 20 ID
 29 Address

0

참고 : 여기에서 색인으로 가정하면 단어의 시작 부분이 아닌 문자열의 어떤 문자 가 아닌 어떤 단어 인지 (0에서 시작) 알고 싶다는 의미 입니다. 다른 답변은 후자를 언급합니다.

내가 아는 바는 없지만 만들 수 있습니다. 두 가지 트릭 :

  1. for 구문 의 선천적 능력을 사용하여 인용되지 않은 입력을 공백으로 나눕니다.
  2. 원하는 열을 찾을 수없는 경우를 처리하십시오. 이 경우, 발견 된 인덱스를 stout에 보내고 상태 코드가 찾기 성공 여부를 표시하도록 선택했습니다. 다른 가능성이 있습니다.

암호:

#!/bin/bash
find_index() {
    local str=$1
    local search=$2
    let local n=0
    local retval=1 # here, 1 is failure, 0 success
    for col in $str; do # $str unquoted -> whitespace tokenization!
    if [ $col = $search ]; then
        echo $n
        retval=0
        break
    else
        ((n++))
    fi
    done
    return $retval
}

test="Name   Age Sex  ID         Address"
idx=`find_index "$test" Age`
if [ $? -ne 0 ]; then
    echo "Not found!"
else
    echo "Found: $idx"
fi

0

쉘에서 다음 자바 스크립트 oneliner를 사용해보십시오 (javascript 쉘 사용).

$ js <<< "x = 'Name   Age Sex  ID         Address'; print(x.indexOf('Age'));"
7

또는 here-doc을 사용하십시오.

js <<EOF
x = 'Name   Age Sex  ID         Address';
print(x.indexOf('Age'));
EOF

0

잘 작동하는 솔루션을 찾았습니다.

$ string = '지금은 시간입니다'
$ buf = the $ {string # * the}
$ echo $ buf
출력 : 시간
$ index = $ (($ {# string}-$ {# buf} + 1))
$ echo $ index
출력 : 8-> 첫 단어 "the"의 색인

입력 문자열의 첫 번째 발생을 리턴하는 Java의 indexOf () 함수와 유사하게 작동합니다.

이 솔루션은 여기 http://www.linuxquestions.org/questions/linux-newbie-8/bash-string-manipulation-help-670627/ (마지막 게시물)에 있습니다. 이 사람은 내 하루를 구했다. 그에게 신용.

첫 번째 indexof에서 하위 문자열을 수행하려는 경우 더 빠른 방법입니다.

$ a = "일부 긴 문자열"
$ b = "ri"
$ echo $ {a / * $ b / $ b}

$ echo $ {a / $ b * / $ b}
긴 줄

/programming/10349102/shell-script-substring-from-first-indexof-substring


0

coreutils가 사용 가능한 경우 다음과 같은 방법으로 수행 할 수 있습니다.

에코 $ {str / Age //} | 컷 -d / -f1 | 화장실 -w

MariusMatutiae 요청에 따라이 3 단계 작업이 어떻게 작동하는지 설명을 추가하고 있습니다.

echo $ {str / Age //} 1. 고유 문자를 검색하는 문자열을 교체하십시오 (내 경우에는 /)

cut -d / -f1 2. 고유 한 문자 다음에 오는 문자열의 전체 부분을 잘라냅니다.

wc -w 3. 남은 단어를 세고 인쇄하여 색인 번호를 알려줍니다.

참고로 다음을 확인하십시오.

http://www.tldp.org/LDP/abs/html/parameter-substitution.html ( "가변 확장 / 하위 문자열 대체"로 이동)
http://www.gnu.org/software/coreutils/manual/coreutils .html ( "cut 명령"및 "wc 호출"로 이동)


이것은 당면한 문제를 해결하지만 이러한 간결한 답변은이 사이트들에서 눈살을 찌푸리게합니다. 이것이 왜 효과가 있는지 정확히 설명하는 몇 단어를 쓰는 것이 더 도움이 될 것입니다. 이렇게하십시오.
MariusMatutiae

0

순수한 bash 배열과 부분 문자열 대체를 사용하여 이전에 주어진 두 가지 대답이 혼합되어 있습니다.

아이디어는 원하는 단어보다 먼저 모든 단어의 문자열을 얻은 다음 배열로 만들어 해당 하위 문자열의 단어 수를 계산하는 것입니다.

$ haystack="Name   Age Sex  ID         Address"
$ words_before=( ${haystack%Age*} )     # truncate string, make array
$ echo ${#words_before[*]}              # count words in array
1

물론 Age는 다른 변수에 저장 needle한 다음 사용할 수 있습니다 ${haystack%$needle*}. 검색 한 단어가 다른 단어의 일부인 경우 문제가 발생합니다.이 경우 kopischke의 답변이 여전히 작동합니다.


0

이것은 7 살짜리 질문이지만 일부는 순수한 bash로 대답이 필요할 수 있습니다.

STRING="Name   Age Sex  ID         Address"
INDEXOF_AGE=${#${STRING/Age*/}}
echo $INDEXOF_AGE
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.