셸 스크립팅에서 문자열의 처음 두 문자를 추출하려면 어떻게 해야 합니까?
예를 들어, 다음과 같습니다.
USCAGoleta9311734.5021-120.1287855805
다음과 같이 추출합니다.
US
아마도 가장 효율적인 방법일 것입니다, 만약 당신이 그것을 사용한다면.bash
셸(그리고 당신의 주석에 따르면 당신은)은 매개 변수 확장의 하위 문자열 변형을 사용하는 것입니다.
pax> long="USCAGol.blah.blah.blah"
pax> short="${long:0:2}" ; echo "${short}"
US
이것은 설정될 것입니다.short
물되는이인의 첫 두 것long
.한다면long
두문보자 다 짧 습 니 다 니 짧short
그것과 동일할 것입니다.
일반적으로 이 인셸 방법은 프로세스 생성 오버헤드가 없기 때문에 보고서당 50,000회 정도의 작업을 자주 수행하는 경우에 더 좋습니다.외부 프로그램을 사용하는 모든 솔루션은 이러한 오버헤드로 인해 어려움을 겪을 것입니다.
또한 최소 길이를 보장하려면 다음과 같은 방법으로 미리 패드를 넣을 수 있습니다.
pax> long="A"
pax> tmpstr="${long}.."
pax> short="${tmpstr:0:2}" ; echo "${short}"
A.
이렇게 것이 마침표로 수 ▁used▁creating▁this▁character▁the를▁when,▁by▁else▁changing▁(▁would▁ensure다이▁charact▁padded▁on▁less▁justorers패니것(▁was▁periods렇▁that▁anything▁with됩오표▁in▁something딩▁the▁two). 생성 시 사용되는 문자를 변경하는 것만으로tmpstr
) 완성도를 이것이 필요한지 확실하지 않지만 완성도를 위해 넣으려고 생각했습니다.
외부 를 들어, 하외예프이로으수방램있다여습니가경우가지러법은는행그하작없업렇는긴지을만로그부예▁having▁you▁(▁as▁if▁programs▁there▁don▁that(,such▁said▁to우경▁with다▁havet: ▁this▁external▁any는없니습있그▁are▁do▁number렇)bash
사용 가능), 그 중 일부는 다음과 같습니다.
short=$(echo "${long}" | cut -c1-2)
short=$(echo "${long}" | head -c2)
short=$(echo "${long}" | awk '{print substr ($0, 0, 2)}'
short=$(echo "${long}" | sed 's/^\(..\).*/\1/')
두개 (처음두개개(두▁the처▁(▁first음)cut
그리고.head
는 한 문자열에 . 으로 둘 다 두 는 한 줄의 문자열에 대해 동일합니다. 기본적으로 둘 다 처음 두 문자만 반환합니다.는 점에서 차이가 있습니다.cut
각 행의 처음 두 문자를 제공합니다.head
전체 의 첫 두 가 나옵니다.
세 번째는 다음을 사용합니다.awk
두하는 서브 문자열 와 네 를 사용하는 서브 문자열 함수입니다.sed
groups ()()
그리고.\1
두하고 전체 행을 로 바꿉니다 처음 두 문자를 캡처하고 전체 행을 이 문자로 바꿉니다.은 둘 다 비슷합니다.cut
입력에서 각 행의 처음 두 문자를 전달합니다.
입력이 한 줄로 되어 있다고 확신할 경우 모두 동일한 효과를 얻을 수 있습니다.
가장 쉬운 방법은 다음과 같습니다.
${string:position:length}
이 추된위치를 추출하는 곳.$length
에 된파생에서 된 문자열$string
$position
.
이것은 내장된 Bash이므로, 어색하거나 sed가 필요하지 않습니다.
가지 때문에 저도 배쉬 , 이 당은몇 가좋답얻나었고을는내로것다이내후이질배가당한문하선지신이신장만택쉬할된를지은▁about▁you▁you▁asked▁builtin로이,▁myself▁with▁but▁bash당▁and후▁the질▁since신한▁i▁good''▁several.sed
그리고.awk
그리고 (거의) 아무도 이를 기반으로 한 솔루션을 제공하지 않았습니다. 저는 다음과 같이 제안합니다.
echo "USCAGoleta9311734.5021-120.1287855805" | awk '{print substr($0,1,2)}'
그리고.
echo "USCAGoleta9311734.5021-120.1287855805" | sed 's/\(^..\).*/\1/'
그awk
하나는 꽤 분명해야 하지만, 여기에 대한 설명이 있습니다.sed
아래쪽:
- 대체 "s/"
- 행 "^"의 시작 부분에서 시작하여 "."가 이어지는 두 문자의 그룹("), "."이 0회 이상 반복됨(일부 특수 문자를 이스케이프하려면 백슬래시가 필요함)
- 첫 번째(그리고 이 경우에만 해당) 그룹의 내용 "/"에 의해(여기서 백슬래시는 일치하는 하위 표현을 참조하는 특수 이스케이프입니다).
- 완료 "/"
그냥 grep:
echo 'abcdef' | grep -Po "^.." # ab
만약 당신이 참여한다면bash
다음과 같이 말할 수 있습니다.
bash-3.2$ var=abcd
bash-3.2$ echo ${var:0:2}
ab
이것이 바로 여러분이 필요로 하는 것일 수도 있습니다.
셸 스크립팅을 사용하고 비포식스 확장(예: 바시즘)에 의존하지 않으려면 grep, sed, cut, awk 등과 같은 포킹 외부 도구가 필요 없는 기술을 사용하면 스크립트의 효율성이 떨어집니다.사용 사례에서 효율성과 posix 휴대성은 중요하지 않을 수 있습니다.그러나 이 경우(또는 좋은 습관일 경우) 다음 매개 변수 확장 옵션 방법을 사용하여 셸 변수의 처음 두 문자를 추출할 수 있습니다.
$ sh -c 'var=abcde; echo "${var%${var#??}}"'
ab
이것은 "가장 작은 접두사" 매개 변수 확장을 사용하여 처음 두 문자를 제거합니다.${var#??}
part), 그 다음 "확장 접미사" 매개 변수 확장(the${var%
part에서 처음 두를 제외한 모든 합니다.
이 방법은 이전에 "Shell = Check if variable이 #로 시작하는지 확인" 질문에 대한 답변에서 설명했습니다.이 대답은 또한 여기서 원래 질문에 적용되는 것과 약간 다른 맥락에서 사용될 수 있는 몇 가지 유사한 매개 변수 확장 방법을 설명합니다.
사용할 수 있습니다.printf
:
$ original='USCAGoleta9311734.5021-120.1287855805'
$ printf '%-.2s' "$original"
US
colrm — 파일에서 열 제거
처음 두 개의 문자를 남기려면 3부터 시작하는 열만 제거합니다.
cat file | colrm 3
사용:
sed 's/.//3g'
또는
awk NF=1 FPAT=..
또는
perl -pe '$_=unpack a2'
단지 재미를 위해 저는 그것들이 너무 복잡하고 쓸모가 없지만, 언급되지 않았다는 것을 몇 가지 덧붙입니다.
head -c 2 <( echo 'USCAGoleta9311734.5021-120.1287855805')
echo 'USCAGoleta9311734.5021-120.1287855805' | dd bs=2 count=1 status=none
sed -e 's/^\(.\{2\}\).*/\1/;' <( echo 'USCAGoleta9311734.5021-120.1287855805')
cut -c 1-2 <( echo 'USCAGoleta9311734.5021-120.1287855805')
python -c "print(r'USCAGoleta9311734.5021-120.1287855805'[0:2])"
ruby -e 'puts "USCAGoleta9311734.5021-120.1287855805"[0..1]'
셸을 하고 있는 (not 시에서사다셸사경는우하용경우않는지용을하스른템사▁if(경▁(▁a▁your▁isnot)경)bash
), 에는 ), "는 다음과 같은 기능이 있습니다bash
그러면 당신은 여전히 고유한 문자열 조작을 사용할 수 있습니다.bash
을 bash
변수 포함:
strEcho='echo ${str:0:2}' # '${str:2}' if you want to skip the first two characters and keep the rest
bash -c "str=\"$strFull\";$strEcho;"
유니코드 + UTF-8을 고려하는 방법
바이트가 아닌 유니코드 문자에 관심이 있는 사용자를 대상으로 간단한 테스트를 수행해 보겠습니다.의 각 문자áéíóú
UTF-8에서는 2바이트로 구성되어 있습니다.
printf 'áéíóú' | LC_CTYPE=en_US.UTF-8 awk '{print substr($0,1,3);exit}'
printf 'áéíóú' | LC_CTYPE=C awk '{print substr($0,1,3);exit}'
printf 'áéíóú' | LC_CTYPE=en_US.UTF-8 head -c3
echo
printf 'áéíóú' | LC_CTYPE=C head -c3
다음을 확인:
áéí
á
á
á
그래서 우리는 그것만 봅니다.awk
+LC_CTYPE=en_US.UTF-8
UTF-8 문자로 간주됩니다.다른 접근 방식은 3바이트만 소요되었습니다.다음을 통해 확인할 수 있습니다.
printf 'áéíóú' | LC_CTYPE=C head -c3 | hd
이는 다음을 제공합니다.
00000000 c3 a1 c3 |...|
00000003
리고그고.c3
그 자체가 쓰레기이고, 터미널에 나타나지 않기 때문에, 우리는 단지 보았습니다.á
.
awk
+LC_CTYPE=en_US.UTF-8
하지만 실제로는 6바이트를 반환합니다.
또한 다음을 사용하여 동등한 테스트를 수행할 수도 있습니다.
printf '\xc3\xa1\xc3\xa9\xc3\xad\xc3\xb3\xc3\xba' | LC_CTYPE=en_US.UTF-8 awk '{print substr($0,1,3);exit}'
일반 매개 변수를 원하는 경우:
n=3
printf 'áéíóú' | LC_CTYPE=en_US.UTF-8 awk "{print substr(\$0,1,$n);exit}"
유니코드 + UTF-8에 대한 더 구체적인 질문: https://superuser.com/questions/450303/unix-tool-to-output-first-n-characters-in-an-utf-8-encoded-file
관련: https://unix.stackexchange.com/questions/3454/grabbing-the-first-x-characters-for-a-string-from-a-pipe
Ubuntu 21.04에서 테스트되었습니다.
이것이 당신이 추구하는 것일 수도 있습니다.
my $string = 'USCAGoleta9311734.5021-120.1287855805';
my $first_two_chars = substr $string, 0, 2;
참조: 하위 항목
perl -ple 's/^(..).*/$1/'
코드
if mystring = USCAGoleta9311734.5021-120.1287855805
print substr(mystring,0,2)
미국을 인쇄할 것입니다.
여기서 0은 시작 위치이고 2는 읽을 문자 수입니다.
언급URL : https://stackoverflow.com/questions/1405611/how-can-i-extract-the-first-two-characters-of-a-string-in-shell-scripting
'programing' 카테고리의 다른 글
특정 단어에 대한 Git 커밋 디프 또는 내용을 grep하는 방법 (0) | 2023.04.29 |
---|---|
전체 배열을 지우는 방법은 무엇입니까? (0) | 2023.04.29 |
한 디브를 다른 디브 위에 덧씌우는 방법 (0) | 2023.04.29 |
셸 스크립트에서 백틱 대신 $()를 사용하면 어떤 이점이 있습니까? (0) | 2023.04.29 |
C# LINQ 목록에서 중복 항목 찾기 (0) | 2023.04.29 |