source

셸에서 문자열을 분할하여 마지막 필드를 가져오는 방법

ittop 2023. 4. 22. 10:28
반응형

셸에서 문자열을 분할하여 마지막 필드를 가져오는 방법

내가 그 끈을 가지고 있다고 가정해봐1:2:3:4:5마지막 필드를 취득하고 싶다.5(이 경우)를 참조해 주세요.Bash를 사용해서 어떻게 하죠?나는 노력했다.cut단, 마지막 필드를 지정하는 방법은 모릅니다.-f.

문자열 연산자를 사용할 수 있습니다.

$ foo=1:2:3:4:5
$ echo ${foo##*:}
5

이렇게 하면 앞에서부터 ':'까지 모든 것이 탐욕스럽게 다듬어집니다.

${foo  <-- from variable foo
  ##   <-- greedy front trim
  *    <-- matches anything
  :    <-- until the last ':'
 }

또 다른 방법은 이전과 이후를 반대로 하는 것입니다.cut:

$ echo ab:cd:ef | rev | cut -d: -f1 | rev
ef

이렇게 하면 마지막 필드 이외의 필드 또는 끝부터 번호가 매겨진 필드 범위를 쉽게 얻을 수 있습니다.

컷을 사용하여 마지막 필드를 얻는 것은 어렵지만 awk와 perl의 몇 가지 솔루션이 있습니다.

echo 1:2:3:4:5 | awk -F: '{print $NF}'
echo 1:2:3:4:5 | perl -F: -wane 'print $F[-1]'

매우 간단한 사용법(예를 들어 딜리미터의 이스케이프 없음)을 전제로 grep를 사용할 수 있습니다.

$ echo "1:2:3:4:5" | grep -oE "[^:]+$"
5

분류 - 줄 끝의 구분 기호($)가 아닌 모든 문자를 찾습니다. -o는 일치하는 부분만 인쇄합니다.

이런걸 써보시면 됩니다.cut:

echo "1:2:3:4:5" | cut -d ":" -f5

를 사용할 수도 있습니다.grep다음과 같이 시도합니다.

echo " 1:2:3:4:5" | grep -o '[^:]*$'

편도:

var1="1:2:3:4:5"
var2=${var1##*:}

다른 하나는 어레이를 사용하는 경우:

var1="1:2:3:4:5"
saveIFS=$IFS
IFS=":"
var2=($var1)
IFS=$saveIFS
var2=${var2[@]: -1}

또 다른 어레이:

var1="1:2:3:4:5"
saveIFS=$IFS
IFS=":"
var2=($var1)
IFS=$saveIFS
count=${#var2[@]}
var2=${var2[$count-1]}

Bash(버전>= 3.2) 정규 표현 사용:

var1="1:2:3:4:5"
[[ $var1 =~ :([^:]*)$ ]]
var2=${BASH_REMATCH[1]}
$ echo "a b c d e" | tr ' ' '\n' | tail -1
e

딜리미터를 새 행으로 변환하고 마지막 엔트리를 선택합니다.tail -1.

사용.sed:

$ echo '1:2:3:4:5' | sed 's/.*://' # => 5

$ echo '' | sed 's/.*://' # => (empty)

$ echo ':' | sed 's/.*://' # => (empty)
$ echo ':b' | sed 's/.*://' # => b
$ echo '::c' | sed 's/.*://' # => c

$ echo 'a' | sed 's/.*://' # => a
$ echo 'a:' | sed 's/.*://' # => (empty)
$ echo 'a:b' | sed 's/.*://' # => b
$ echo 'a::c' | sed 's/.*://' # => c

여기에는 좋은 답변이 많이 있습니다만, 그래도 basename을 사용하여 이것을 공유하고 싶습니다.

 basename $(echo "a:b:c:d:e" | tr ':' '/')

그러나 문자열에 '/'이(가) 이미 있으면 실패합니다.slash /가 딜리미터인 경우 basename을 사용해야 합니다(그리고 basename을 사용해야 합니다.

최선의 답은 아니지만 bash 명령어를 사용하여 창의력을 발휘할 수 있는 방법을 보여줍니다.

마지막 필드가 단일 문자일 경우 다음을 수행할 수 있습니다.

a="1:2:3:4:5"

echo ${a: -1}
echo ${a:(-1)}

bash 문자열 조작을 확인합니다.

Bash 사용.

$ var1="1:2:3:4:0"
$ IFS=":"
$ set -- $var1
$ eval echo  \$${#}
0
echo "a:b:c:d:e"|xargs -d : -n1|tail -1

먼저 xargs split을 ":"를 사용하여 분할합니다.-n1은 각 행에 1개의 부분만 있음을 의미합니다.그리고 마지막 부분을 삐걱거리면서.

정규식 매칭sed(항상 마지막 오카렌스로 넘어갑니다)는, 다음과 같은 이점을 얻을 수 있습니다.

$ foo=1:2:3:4:5
$ echo ${foo} | sed "s/.*://"
5

읽기 기능을 사용한 솔루션:

IFS=':' read -a fields <<< "1:2:3:4:5"
echo "${fields[4]}"

또는 좀 더 일반적이게 하기 위해:

echo "${fields[-1]}" # prints the last item
for x in `echo $str | tr ";" "\n"`; do echo $x; done

@mateusz-piotrowski@user3133260의 답변에서 개선됩니다.

echo "a:b:c:d::e:: ::" | tr ':' ' ' |  xargs | tr ' ' '\n' | tail -1

먼저 tr ':' ' -> ':'를 공백으로 바꿉니다.

그리고 xargs로 다듬는다.

그 후 tr '\n' -> 공백이 남아 있는 행을 newline으로 바꿉니다.

마지막으로 tail -1 -> 마지막 문자열을 가져옵니다.

Python에 익숙한 사용자에게 https://github.com/Russell91/pythonpy은 이 문제를 해결하기 위한 좋은 선택입니다.

$ echo "a:b:c:d:e" | py -x 'x.split(":")[-1]'

pythonpy ::: :-x treat each row of stdin as x.

이 툴을 사용하면 입력에 적용되는 python 코드를 쉽게 작성할 수 있습니다.

편집(2020년 12월):Pythonpy는 더 이상 온라인 상태가 아닙니다.대체 방법은 다음과 같습니다.

$ echo "a:b:c:d:e" | python -c 'import sys; sys.stdout.write(sys.stdin.read().split(":")[-1])'

많은 코드 "Code")가 되어 있습니다.sys.stdout.read/writepython std std.

언급URL : https://stackoverflow.com/questions/3162385/how-to-split-a-string-in-shell-and-get-the-last-field

반응형