Unixスクリプトに問題があります

Unixスクリプトに問題があります

入力する - -

System:root,bin,user,saaa

出力表示----

System,root
System,bin
System,user
System,says

この出力を取得する方法は?

答え1

使うのはいいけどperlシェルスクリプトを指定したので...

ステップ1:文字に従って行を2つの部分に分割します:cutコマンドまたは${parameter#word}構造を使用してください${parameter%word}

ステップ2:行の2番目の部分を役割に応じて複数の部分に分割します,。そのawkコマンドを使用してください - どのくらいのブロックがあるのか​​教えてください。 (私は専門家ではないawkので、これが私が思うように動作するかどうかはわかりません。)

ステップ3:手順2で得られた部品を繰り返し、手順1の最初の部品に貼り付けて印刷します。

答え2

入力行に正確に1つのコロン(:)が含まれていて、,コロンの前にカンマ()が来ることができず、カンマとコロンの両方が抽出された部分文字列の一部になることができない(エスケープされていない)と仮定できれば、awkスクリプトで十分です。

$ printf '%s\n' 'System:one,two,three' |
    awk -v FS=':|,' '{ for (i=2;i<=NF;i++) { print $1","$i } }'

出力:

System,one
System,two
System,three

フィールドFS区切り記号は:すべての文字または,


代わりに、最初のコロン(カンマを含む)の前のすべての項目を最初の出力フィールドとして選択し、入力行の残りの部分をコンマに分割したい場合(カンマが部分的に残っていないと仮定)、部分文字列(なしにもかかわらず)エスケープ)、提案されているようにシェル機能を使用できます。ハイミの答え:

$ printf '%s\n' 'System:one,two,three' |
    while IFS= read -r rem; do      # IFS= to preserve blank characters
      first=${rem%%:*}              # Remove from the first ':' on
      rem=${rem#"$first"}           # Remove first from the beginning of rem
      rem=${rem#:}                  # Strip the remaining ':' at rem's beginning
      while test "$rem"; do         # Exit when rem is empty
          second=${rem%%,*}         # Remove from the first ',' on
          rem=${rem#"$second"}      # Remove second from the beginning of rem
          rem=${rem#,}              # Strip the remaining ',' at rem's beginning
          printf '%s\n' "$first,$second"
      done
    done

ただ理解していることを確認してくださいシェルループを使用してテキストを処理する際の注意事項

またはGNUを使用してくださいsed

$ printf '%s\n' 'System:one,two,three' |
sed -n '
  :l1
    s/^[^:]*:\n//g;
    t l2;
  s/^\([^:]\{1,\}\):\([^,\n]\{1,\}\)*,\{0,1\}\(.*\)$/\1:\3\n\1,\2/;
    t l1;
  q;
  :l2 p;
'

ここでは、分岐(t)からラベル(l1)までを使用して、ループを介して入力の各行を処理します。一度に1つずつ、最初:と最初の次の間の部分文字列がパターン,スペースに新しい行として追加され、最初の前の部分文字列の後に連結されます:。抽出する部分文字列がもう存在しない場合は、元の文字列の残りの部分が削除され、パターンスペースが印刷され、プログラムが終了します。

(GNUsedバージョン> = 4.6の場合は、optionsを使用して呼び出して進行状況を段階的に確認できます--debug)。

\n内部角かっこ式を使用して文字を一致させること(ここでは否定一致)<newline>は標準ではありません。 POSIX は、<backslash>そのコンテキストで特別な意味が失われることを指定します。

関連情報