以下の入力ファイルがあります。
N1518 AMP,AUG,AZM,CHL
N1520 AZM,NAL
N1524 AMP,NAL,STR
......
に変換しようとしています。
N1518 AMP
N1518 AUG
N1518 AZM
N1518 CHL
N1520 AZM
N1520 NAL
N1524 AMP
N1524 NAL
N1524 STR
....
これができるライナーはありますか?
答え1
この試み、
awk -F '[\t,]' '{for (i=2;i<NF;i++) print $1"\t"$i}' file
N1518 AMP
N1518 AUG
N1518 AZM
N1518 CHL
N1520 AZM
N1524 AMP
N1524 NAL
答え2
複数の区切り文字でawkを使用してから、フィールドを繰り返して列を印刷できます。
awk -F'[ ,]+' '{for (i=2;i<=NF;i++) {printf "%s %s\n",$1,$i;}}' file
説明する:
-F'[ ,]+'
: これは awk にスペースとカンマをフィールド区切り文字として使用するように指示します。また、連続した区切り文字を単一の区切り文字として扱うように指示します。
for (i=2;i<=NF;i++)
:最初の列を繰り返し印刷する必要があるため、2番目の列から始めてすべての列を繰り返します。
printf "%s %s\n",$1,$i;
:最初の列とi番目の列を含む行を印刷します。
答え3
次のスクリプトを使用してテストしてみると、効果も非常に良いです。
行数 =awk '{print NR}' filename| sort -nr| sed -n '1p'
for ((i=1;i<=$count_line;i++)); do fi=`awk -v i="$i" 'NR==i{print $1}' filename`; h=`awk -v i="$i" 'NR==i{print $2}' filename|awk -F "," '{print NF}'| sort -nr | sed -n '1p'`; for ((j=1;j<=$h;j++)); do echo $fi;awk -v i="$i" -v j="$j" 'NR==i{print $2}' filename| awk -v j="$j" -F "," '{print $j}' ; done; done|sed "N;s/\n/ /g"
出力
N1518 AMP
N1518 AUG
N1518 AZM
N1518 CHL
N1520 AZM
N1520 NAL
N1524 AMP
N1524 NAL
N1524 STR
答え4
GNU sed
拡張正規表現パターンオプションを使用すると、-E
次のように問題を実装できます。
$ sed -Ee 's/^((\S+\t)[^,]+),/\1\n\2/;P;D' inp
出力:
N1518 AMP
N1518 AUG
N1518 AZM
N1518 CHL
N1520 AZM
N1520 NAL
N1524 AMP
N1524 NAL
N1524 STR