区切り文字で長い行を分割します。

区切り文字で長い行を分割します。

次のように入力を分割するにはどのコマンドを使用できますか?

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"

関連情報