구분 기호로 긴 줄을 분할합니다.

구분 기호로 긴 줄을 분할합니다.

다음과 같이 입력을 분할하려면 어떤 명령을 사용할 수 있습니까?

foo:bar:baz:quux

이것에 들어가나요?

foo
bar
baz
quux

명령 을 알아내려고 노력 중인데 cut"처음 1000자" 또는 "처음 7개 필드"와 같이 고정된 양의 입력에만 작동하는 것 같습니다. 임의로 긴 입력을 처리해야 합니다.

답변1

몇 가지 옵션이 있습니다:

  • tr : \\n
  • sed 's/:/\n/g'(GNU sed 사용)
  • awk '{ gsub(":", "\n") } 1'

pure로도 이 작업을 수행할 수 있습니다 bash.

while IFS=: read -ra line; do
    printf '%s\n' "${line[@]}"
done

답변2

$ line=foo:bar:baz:quux
$ words=$(IFS=:; set -- $line; printf "%s\n" "$@")
$ echo "$words"
foo
bar
baz
quux

답변3

grep이 지원하는 경우 -o다음을 수행할 수 있습니다.

grep -o '[^:]\+'

또는 awk를 사용하여 레코드 구분 기호를 다음으로 설정합니다 :.

awk -v RS=: 1

또는 GNU 컷을 사용하세요.

cut -d: --output-delimiter=$'\n' -f1-

편집하다

RSChris가 아래에서 지적했듯이, 이로 인해 후행 개행 문자가 남게 됩니다. 이는 awk 지원이 정규식으로 지정되면 피할 수 있습니다(GNU awk로 테스트됨).

awk -v RS='[:\n]' 1

답변4

순수한 Bash 솔루션은 끝에 ':'를 사용하세요.

## Split string, store in array:
IFS=: read -ra arr <<< "$line:X"    # pad to prevent skipping an empty last field
unset "arr[ ${#arr[@]} - 1 ]"       # pop last element

line=foo:bar:

## wrong:
IFS=: read -ra arr <<< "$line"      # common method
declare -p arr                      # output: ... '([0]="foo" [1]="bar")'

## correct:
IFS=: read -ra arr <<< "$line:X"    # pad at end to prevent skipping a last empty field
unset "arr[ ${#arr[@]} - 1 ]"       # pop last element
declare -p arr                      # output: ... '([0]="foo" [1]="bar" [2]="")'

## output as records ####
for j in "${arr[@]}"; do echo "$j"; done  # output is "foo\nbar\n\n"

관련 정보