在分隔符上分割长行

在分隔符上分割长行

我可以使用什么命令来分割输入,如下所示:

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-

编辑

RS正如下面 Chris 所指出的,这将留下一个尾随换行符,如果您的 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"

相关内容