답변:
-b
바이트 오프셋을 얻는 데 사용할 수 있습니다 . 이는 간단한 텍스트의 위치와 동일하지만 UTF-8 또는 이와 유사한 것은 아닙니다.
$ echo "RAMSITALSKHMAN|1223333" | grep -aob '|'
14:|
위에서는 -a
스위치를 사용하여 grep에게 입력을 텍스트로 사용하도록 지시합니다. 이진 파일을 조작 할 때 필요 -o
하며 일치하는 문자 만 출력하는 스위치입니다.
위치 만 원하는 경우 grep을 사용하여 위치 만 추출 할 수 있습니다.
$ echo "RAMSITALSKHMAN|1223333" | grep -aob '|' | grep -oE '[0-9]+'
14
이상한 출력이 나오면 grep에 색상이 활성화되어 있는지 확인하십시오. --colors=never
grep 에 전달 하거나 grep 명령 앞에 접두사를 붙이면 색상을 비활성화 할 수 있습니다 \
.
$ echo "RAMSITALSKHMAN|1223333" | grep -aob '|' --color=never | \grep -oE '^[0-9]+'
14
여러 개의 일치 항목을 반환하는 문자열의 head -n1
경우 첫 번째 일치 항목을 얻기 위해 연결합니다.
위의 두 가지를 모두 사용하고, 별칭을 사용할 때만 grep이 실행 파일 (스크립트 또는 기타)을 통해 "별칭 화"되면 후자는 작동하지 않습니다.
2
;) 검색
^
:)
0:|
0 행의 시작 부분의 바이트 위치 때문에 output--로 |
발견된다.
grep (GNU grep) 2.27
. 아마도 OS X를 사용하고 있습니까?
시험:
printf '%s\n' 'RAMSITALSKHMAN|1223333.' | grep -o . | grep -n '|'
산출:
15:|
이렇게하면 인덱스 기반 -1의 위치가 제공됩니다.
printf '%s\n' '|' | grep -o . | grep -n '|'
예상대로 인쇄 1
하지 않습니다 0
.
bash 쉘을 사용하는 경우 grep 또는 awk 와 같은 외부 프로세스를 생성하지 않고도 순수하게 내장 된 작업을 사용할 수 있습니다 .
$ str="RAMSITALSKHMAN|1223333"
$ tmp="${str%%|*}"
$ if [ "$tmp" != "$str" ]; then
> echo ${#tmp}
> fi
14
$
이것은 매개 변수 확장 을 사용하여 |
모든 문자열 이 따르는 모든 발생을 제거 하고 임시 변수에 저장합니다. 그런 다음의 색인을 얻기 위해 임시 변수의 길이를 측정하는 것입니다 |
.
(가) 주 if
(가) 경우 확인되어 |
원래 문자열의 모든 존재. 그렇지 않은 경우 임시 변수는 원래 변수와 동일합니다.
또한 이것은 0부터 시작하는 색인을 제공합니다.이 색인 |
은 일반적으로 bash 문자열을 색인 할 때 유용합니다. 그러나 1 기반 색인이 필요한 경우 다음을 수행 할 수 있습니다.
$ echo $((${#tmp}+1))
15
$
awk index
함수를 사용 하여 일치하는 문자의 위치를 반환 할 수 있습니다 .
echo "RAMSITALSKHMAN|1223333"|awk 'END{print index($0,"|")}'
15
Perl의 index
기능을 사용하지 않아도 될 경우 , 이것은 문자가 하나 이상 발생하는보고를 처리합니다.
echo "|abc|xyz|123456|zzz|" | \
perl -nle '$pos=-1;while (($off=index($_,"|",$pos))>=0) {print $off;$pos=$off+1}'
가독성을 위해 파이프 라인은 두 줄로 나뉘어 있습니다.
대상 문자가 발견되면 index
0을 기준으로 양수 값을 반환합니다. 따라서 문자열 "abc | xyz | 123456 | zzz |" 구문 분석시 위치 0, 4, 8, 15 및 19를 리턴합니다.
RAMSITALSKHMAN|1|223333
"expr match"또는 "expr index"를 사용하여 수행 할 수도 있습니다.
expr match $ string $ substring 여기서 $ substring은 RE입니다.
echo `expr match "RAMSITALSKHMAN|1223333" '[A-Z]*.|'`
그리고 위는 일치하는 부분 문자열의 길이를 반환하기 때문에 위치를 알려줍니다.
그러나 색인 검색에 대해 더 구체적으로 설명하십시오.
mystring="RAMSITALSKHMAN|122333"
echo `expr index "$mystring" '|'`
awk
파일의 모든 라인 에서이 정보를보고하기 위해 솔루션을 사소하게 수정할 수 있기 때문에 ( END
JRFerguson의 답변에서 실제로 필요하지 않은을 제거하기 만하면됩니다 .Avinash Raj는 이미 수행합니다) ; 반면 expr
솔루션으로 그렇게하려면 명시 적 루프를 추가해야합니다 (그리고 Gnouc의 대답은 쉽게 볼 수 없으며, 내가 볼 awk
수 있음 ). (2) 솔루션은 모든 것을보고하도록 조정할 수 있습니다. 각 라인에서 expr
솔루션 보다 다소 쉽게 일치 합니다 (사실 Avinash Raj의 솔루션도 이미 그렇게합니다).
echo `...`
여기서 사용 하겠습니까?
$ echo 'RAMSITALSKHMAN|1223333'| awk 'BEGIN{ FS = "" }{for(i=1;i<=NF;i++){if($i=="|"){print i;}}}'
15
필드 구분 기호를 null 문자열로 설정하면 awk는 레코드의 개별 문자를 별도의 필드로 바꿉니다.
일부 대안은 다음과 같습니다.
Gnouc의 답변과 비슷하지만 껍질이 있습니다.
echo 'RAMSITALSKHMAN|1223333' |
tr -c \| \\n |
sh
sh: line 15: syntax error near unexpected token `|
sh: line 15: `|'
로 sed
하고 dc
가능한 여러 줄에 걸쳐 :
echo 'RAMSITALSKHMAN|1223333' |
sed 's/[^|]/1+/g;s/|/p/;1i0 1+' |dc
15
와 함께 $IFS
...
IFS=\|; set -f; set -- ${0+RAMSITALSKHMAN|1223333}; echo $((${#1}+1))
그것은 또한 얼마나 많은지 알려줄 것입니다 ...
echo $(($#-1))