現在のドキュメントには、何千人ものユーザーの名前、資格情報、役割、権限がリストされています。 .xlsに渡されましたが、行と列が正しい形式でソートされていません。 awkとsedを使用して元のファイルの形式を再指定しましたが、次の一貫した形式の行がたくさんあります。
ID ;email ;role ;privilege ;access-to
8charID1 ;[email protected] ;usr ;read ;finance ;HR ;accounting; dev
8charID2 ;[email protected] ;mgr ;rwx ;finance
8charID3 ;[email protected] ;usr ;rx ;marketing ;dev ;doc
.
.
n x 1,000 number of users
しかし、次の段階で詰まった。
目的:アクセスされたフィールドが複数ある場合(たとえば、行1または行3)、行を再印刷し、アクセスされたフィールドの数に基づいて以前のすべてのフィールドを再印刷し、アクセスされたフィールドを単一の列に並べ替えます。
ID ;email ;role ;privilege ;access-to
abcuser1 ;[email protected] ;usr ;read ;finance
abcuser1 ;[email protected] ;usr ;read ;HR
abcuser1 ;[email protected] ;usr ;read ;accounting
abcuser1 ;[email protected] ;usr ;read ;dev
user2def ;[email protected] ;mgr ;rwx ;finance
zyxuser3 ;[email protected] ;usr ;rx ;marketing
zyxuser3 ;[email protected] ;usr ;rx ;dev
zyxuser3 ;[email protected] ;usr ;rx ;publication
.
.
.
n x 1,000 number of users
答え1
awk -F';' -v OFS=';' '
{ for (i=5; i<=NF; i++) print $1,$2,$3,$4,$i }
' file
出力
ID ;email ;role ;privilege ;access-to
8charID1 ;[email protected] ;usr ;read ;finance
8charID1 ;[email protected] ;usr ;read ;HR
8charID1 ;[email protected] ;usr ;read ;accounting
8charID1 ;[email protected] ;usr ;read ; dev
8charID2 ;[email protected] ;mgr ;rwx ;finance
8charID3 ;[email protected] ;usr ;rx ;marketing
8charID3 ;[email protected] ;usr ;rx ;dev
8charID3 ;[email protected] ;usr ;rx ;doc
答え2
Glennのソリューションと同じ基本的なアイデアがありますが、Perlでは次のようになります。
$ perl -F";" -lane '$"=";";print "@F[0..3];", $_ for @F[4..$#F]' file
ID ;email ;role ;privilege ;access-to
8charID1 ;[email protected] ;usr ;read ;finance
8charID1 ;[email protected] ;usr ;read ;HR
8charID1 ;[email protected] ;usr ;read ;accounting
8charID1 ;[email protected] ;usr ;read ; dev
8charID2 ;[email protected] ;mgr ;rwx ;finance
8charID3 ;[email protected] ;usr ;rx ;marketing
8charID3 ;[email protected] ;usr ;rx ;dev
8charID3 ;[email protected] ;usr ;rx ;doc
説明する
-a
:Perlを同様に動作させ、awk
自動的に各行を空白のフィールドに分割し(デフォルトでは参照-F
)@F
、配列に保存します。-e
:コマンドラインにスクリプトを提供できます。-n
:入力ファイルを1行ずつ読みます。-l
print
:末尾の改行を削除し、各呼び出しに改行を追加します。-F
:と同様に、awk
入力フィールドの区切り記号です。ここでは に設定しました;
。
もちろん、スクリプトは少し難しいですが、アルゴリズムは非常に簡単です。最初の4つのフィールドを印刷し、各フィールドに対して> 4を繰り返します。
$"=";"
: 特殊変数は$"
リスト区切り文字です。これは、配列を印刷すると、配列の各要素間に印刷されます。ここでは;
、必要に応じてフィールドリストを印刷できるように設定しました。@F[0..3]
:配列スライスです。配列の最初の4つの要素です@F
(;
現在行の - 区切りフィールド)。@F[4..$#F]
:別の配列スライス。これは、5番目の要素から@F
最後の要素($#array
Perlの配列の最大インデックス)までです。
完全な印刷コマンドは単に寛容なPerlコマンドです:
## For each element of the array slice
foreach $field (@F[4..$#F]){
## print the first 4 fields and a ';', The fields
## are printed separated by ";" because of the $" above.
print "@F[0..3];";
## In the golfed version, the $_ is equivalent to $field here
print "$field\n"
}