문자열 앞에서 문자를 '삭제'/ 삭제하는 방법은 무엇입니까?


13

조작하려는 문자열이 있습니다. 문자열은 H08W2345678어떻게 처리 할 수 ​​있으므로 출력이 그대로 W2345678입니까?

는 I가에서 마지막 네 문자를 삭제하고 싶었 마찬가지로 만약 H08W2345678내가 얻을 그래서 H08W234내가 이런 짓을 했을까 방법?


1
문자열을 조작하는 방법에는 여러 가지가 있습니다. 사용하는 특별한 이유가 sed있습니까?
don_crissti

@don_crissti 경험 부족을 제외하고 이유가 없습니다. 모든 대안은 환영합니다 ...
3kstc

@don_crissti, 이야기 : 필터링 된 CSV 파일에서 한 줄의 매개 변수 중 하나를 가져 와서 H08W2345678조작해야합니다. W2345678다른 데이텀과 함께이 값은 전송 된 전자 메일에 저장됩니다. cron으로 이메일을 보내 게됩니다.
3kstc

@don_crissti awking. 배열을 만든 다음 배열 내의 각 요소를 수정합니다 (예 : Epoch 타임 스탬프를 초 단위로 날짜 등으로 변경)
3kstc

2
awk를 사용하여 이와 같은 작업을 수행 할 수 있습니다.printf %s\\n "XX,H08W2345678,YY" | awk -F, '{print substr($2, 4); print substr($2, 1, length($2)-4)}'
don_crissti

답변:


19

bash (또는 ksh93그 구문이 나오는 곳 zsh)을 사용하십시오.

string="H08W2345678"

echo "${string:3}"
W2345678

echo "${string:0:-4}"
H08W234

문자열 조작 에 대한 자세한 내용은 Wooledge 위키를 참조하십시오 .


이것은 bash 4.2 이상이 필요합니다. 참조 배쉬 참조 설명서의이 오래된 사본, 제 3.5.3 ','쉘 매개 변수 확장 ' 또는 여기에 병아리의 대답은 기존의 제약 조건을보고 ( " 길이 보다 숫자 이상으로 평가하거나 제로로 동일해야합니다."); … (계속)
Scott

(계속)… Bash Hackers Wiki에서 Bash 변경 사항을 보거나 ( 섹션 맨 아래로 스크롤) Case Western Reserve University의 기술 인프라 서비스 조직에서 bash 뉴스를 참조하십시오 (“bash-4.2에 추가”검색). 그런 다음 아래로 스크롤하여 "q."로 이동하여 수정본을 봅니다. ………  "${string:0:${#string}-4}" 길이 $string가 4 이상인 한 bash 버전 4.1에서 작동합니다 .
Scott

추신 : 이것은 또한 abc-e처음 세 문자 를 버릴 때 (당신이 원하는 것을하지 않기 -e때문에) 왼쪽과 같은 문자열을 질식 echo -e시킵니다.
Scott

8
$ echo "H08W2345678" | sed 's/^.\{3\}//'
W2345678

sed 's/^.\{3\}//'처음 세 문자를 찾아 ^.\{3\}공백으로 바꿉니다. 여기서는 ^.문자열의 시작 부분에있는 모든 문자를 일치시키고 (문자열 ^의 시작을 나타냄) \{3\}이전 패턴을 정확히 3 번 일치시킵니다. 따라서 ^.\{3\}처음 세 문자와 일치합니다.

$ echo "H08W2345678" | sed 's/.\{4\}$//'
H08W234

마찬가지로 sed 's/.\{4\}$//'마지막 4자를 공백으로 바꿉니다 ( $문자열의 끝을 나타냄).


1
설명해 주시겠습니까? 's/^.\{3\}//'그리고 's/.\{4\}$//'여전히 sed를 배우면서 많은 감사의
말씀을

@ 3kstc : 수정 사항을 확인하십시오
heemayl

1
단지 몇 문자의 경우, 이후 (나에게) ...대신 사용 .\{3\}하기가 더 쉽습니다 : sed -e 's/^...//' -e 's/....$//' 또는 교대 :가있는 단일 표현식에서 더 쉽습니다 sed -r 's/^...|....$//g'. 삭제할 문자가 몇 개 이상인 경우 /.\{17}\/대신 식을 사용합니다 /.............../.
Johnny

문자열이 -e또는 인 경우 잘못 동작합니다 -n. 물론 "마지막 4 자 삭제"의 의미는 4 자보다 짧은 문자열에 대해서는 정의되어 있지 않지만 누군가 첫 번째 문자 나 마지막 문자 하나 를 삭제하기 위해이 문자를 조정하려는 경우 폭파 할 수 있습니다.
Scott

2

모든 줄이 11 자 (또는 무엇이든) 문자열 인 파일이 있으면 sed사용할 도구입니다. 단일 문자열을 조작하는 것은 좋지만 과잉입니다. 단일 문자열 경우 bash 버전 4.2 이상에 액세스 할 수 있다면 Jason의 대답 이 가장 좋습니다. 그러나 및 구문은 bash (well, bash, ksh93, mksh 및 zsh)에 고유 한 것으로 보입니다 . Shell Command Language의 Open Group Base Specification 에는 보이지 않습니다 . 하위 문자열 확장 (추출)을 지원하지 않는 POSIX 호환 쉘이 붙어 있으면${parameter:offset}${parameter:offset:length}

$ printf "%s\n" "${string#???}"
W2345678

$ printf "%s\n" "${string%????}"
H08W234

처음 세 문자를 삭제하면 왼쪽에있는 것과 같은 문자열을 피하기 위해 printf대신에 사용 합니다 (그리고 원하는 것을하지 않습니다).echoabc-e-eecho -e

그리고 Bourne-family 쉘을 전혀 사용하지 않는 경우 (또는 고대의 POSIX 이전 시스템을 사용하는 경우) 여전히 작동합니다.

$ expr " $string" : ' ...\(.*\)'
W2345678

$ expr " $string" : ' \(.*\)....'
H08W234

여분의 주요 공간의 값에 문제가되지 않도록하는 것입니다 $string 실제되는 expr사업자 (예를 들면, +,  /,  index또는 match) 또는 옵션 (예 :  --, --help또는  --version).


@ Stéphane Chazelas : (1) 40 년 전에 알고 알고 어쨌든 잊어 버린 함정을 상기시켜 주셔서 감사합니다. (2) 나는 항상 이것을 해결하기 위해 사용했다 X. 예를 들어, expr "X$string" : 'X...\(.*\)'. IMO, 읽고 이해하기가 더 쉽습니다. 그것에 문제가 있거나 공간을 선호하는 이유가 있습니까? (3) 오늘 나는 expr + "$string" : '...\(.*\)'지금 작동 한다는 것을 배웠다 . 40 년 전의 기억은 없습니다. 추천하기에 충분히 널리 사용됩니까? (4) jasonwryan의 답변에 대한 메모와 heemayl의 답변에 대한 엄선 된 메모를 놓쳤습니다.
Scott

AFAIK expr +는 GNU에만 해당합니다 (Solaris 나 FreeBSD AFAICS에서는 작동하지 않습니다). x 대신 space를 사용합니다. 일부 expr구현에는 with보다 space로 시작하는 연산자가 x있을 가능성이 적으며 with보다 space로 시작하는 조합 요소가 적기 때문에 x를 사용합니다 x. 그러나 나는 그것이 아마위한 좋은 선택이 아니다 실현 expr " $a" "<" " $b"일부 구현이 수치 비교하면 일을 끝으로 문자열 비교 $a/ $b번호와 같은 모습을. 어쩌면 expr "@@$a"...또는 expr "x $a"안전 할 수 있습니다.
Stéphane Chazelas 2016 년

0

와:

string="H08W2345678"

대부분의 셸에서 3 ~ 4 개의 문자를 일치시키는 것이 간단 해 보입니다

$ printf '%s\t%s\n' "${string#???}" "${string%????}"
W2345678      H08W234

Bourne 쉘과 같은 이전 쉘의 경우 다음을 사용하십시오.

$ string=H08W2345678

$ expr " ${string}" : " ...\(.*\)"
W2345678

$ expr " ${string}" : " \(.*\)...." '
H08W234

숫자가 필요한 경우 다음을 사용하십시오.

$ expr " ${string}" : " .\{3\}\(.*\)"
W2345678

$ expr " ${string}" : " \(.*\).\{4\}" '
H08W234

물론 그 정규 표현식은 sed, awk 및 bash 3.0 이상에서도 작동합니다.

$ echo "$string" | sed 's/^.\{3\}//'
W2345678

$ echo "$string" | sed 's/.\{4\}$//'
H08W234

$ echo "$string" | awk '{sub(/^.{3}/,"")}1'
W2345678

$ echo "$string" | awk '{sub(/.{4}$/,"")}1'
H08W234

$ r='^.{3}(.*)$'; [[ $a =~ $r ]] && echo "${BASH_REMATCH[1]}"
W2345678

$ r='^(.*).{4}$'; [[ $a =~ $r ]] && echo "${BASH_REMATCH[1]}"
H08W234

-1

문자열 앞에서 문자를 '삭제'/ 삭제하는 방법은 무엇입니까?

조작하려는 문자열이 있습니다. 문자열은 H08W2345678입니다. 어떻게 출력을 W2345678로 만들 수 있습니까?

echo "H08W2345678" | cut -c 4-

이것은 질문의 절반에만 답합니다.
Kusalananda

당신의 공감대가 불공평하다고 믿습니다. 끊임없는 질문에 대답 나는 내가 봤 때 한 첫 번째 문자를 제거 POSIX 이 페이지가 검색 결과에 나타나있다. 또한이 페이지 제목은 질문의 정확히 절반 만 다룹니다. 나는 내가 좋아하는 솔루션을 찾았을 때 돌아 왔고 기여했다. 나는 그 직업 cut이이 페이지에있는 것보다 훨씬 우아 하다고 생각한다 .
aexl
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.