
クエリには次の表がありますが、+
区切り文字は、次の例に示すように、「説明」の下に新しい行を作成することです。
TYPE+DESCRIPTION+PRIORITY+DATE
1+text1+HIGH+Aug 15
+text2
2+text+LOW+Aug 11
3+text+LOW+Aug 11
4+text1+HIGH+Aug 15
+text2
+text3
sedを使用して次のように見えるようにするにはどうすればよいですか?
TYPE DESCRIPTION PRIORITY DATE
1 text1 text2 HIGH Aug 15
2 text LOW Aug 11
3 text LOW Aug 11
4 text text2 text3 HIGH Aug 15
私は試した:
sed -n '1{h;n};/^ *+ */{s// /;H;n};{x;s/\n//g;p};${x;p}'
しかし、エラーが発生しました(sed:コマンドが壊れています)。ありがとうございます。
答え1
awk '
BEGIN{OFS=FS="+"}
{sub(/[[:blank:]]+$/,"")} #Removes trailing blanks
NF==4{print line;line=$0}
NF==2{x=$2;$0=line;$2=$2" "x;line=$0}
END{print line}
' file | column -ts "+"
その背後にある主なアイデアは、ifが前の行のNF==2
2番目のフィールド$2
に2番目のフィールドを置くことです。それで何が起こりますか?
1+text1+HIGH+Aug 15 #Puts this in "line" variable
+text2 #Transfer 2nd field to "line" second field
# Resulting in...
1+text1 text2+High+Aug 15
column
+
この微細な最終出力を生成するために出力から削除されました。
TYPE DESCRIPTION PRIORITY DATE
1 text1 text2 HIGH Aug 15
2 text LOW Aug 11
3 text LOW Aug 11
4 text1 text2 text3 HIGH Aug 15
答え2
「ドメイン不可知論」を作るawk
tac file | awk 'BEGIN{FS="+"}
{flds=(NF>flds)?NF:flds;for (i=1; i<=NF; i++) {f=(length($i)>0)?gensub(/ +$/,"","g",$i)" ":"";fld[i]=f fld[i]}}
$1>0{for (i=1; i<=flds; i++) printf fld[i]"+"; printf "\n"; delete fld}' |
tac | column -ts "+"
TYPE DESCRIPTION PRIORITY DATE
1 text1 text2 HIGH Aug 15
2 text LOW Aug 11
3 text LOW Aug 11
4 text1 text2 text3 HIGH Aug 15
牙
$ 1が空でなく設定されているときに印刷する時間であることがわかるように、ファイルを反転します。FS
tac file | awk 'BEGIN{FS="+"}
最大数を計算しflds
、フィールドを繰り返し、切り取り、空白を確認し、フィールドごとに配列にロードして集計します。
{flds=(NF>flds)?NF:flds;for (i=1; i<=NF; i++) {f=(length($i)>0)?gensub(/ +$/,"","g",$i)" ":"";fld[i]=f fld[i]}}
空でない場合は$1
ラインを出力し、配列をリセットします。
$1>0{for (i=1; i<=flds; i++) printf fld[i]"+"; printf "\n"; delete fld}' |
パイプを通してtac
裏返してcolumn
美しくするために使用してください。
tac | column -ts "+"
編集する
2番目のループは本当に気に入らず、パイプのハンマーで打つことがgensub
できるときに各フィールドで停止してテストを簡素化します。sed
優雅な感じではありませんね。
だからここにゴルフをするバージョンはただ感じる私にとってより良い:
tac file | awk 'BEGIN{FS="+"}
{flds=(NF>flds)?NF:flds;
for (i=1; i<=NF; i++) {fld[i]=$i" "fld[i];
if ($1) printf fld[i]"+"}}
$1{ printf "\n"; delete fld}' |
sed -E "s/ +/ /g" | tac | column -ts "+"
答え3
戻って、sedバージョン間の考えられる違いを読んで最初から書き直してください。これがうまくいくことを願っています:
:r
$!N
y:+:,:
/\n,/{
s:^\([^,]\{1,\},[^,]\{1,\}\)\([^\n]\{1,\}\)\n,\([^ \n]\{1,\}\).*$:\1 \3\2:
br
}
$!P
$!D
出力:
TYPE,DESCRIPTION,PRIORITY,DATE
1,text1 text2,HIGH,Aug 15
2,text,LOW,Aug 11
3,text,LOW,Aug 11
4,text1 text2 text3,HIGH,Aug 15
答え4
perl -0pe 'while(s/(.*?)\+(.*?)\+(.*)\n\+(.*)/$1+$2 $4+$3/g){}' file
perl -0
- すべての入力を飲み込むs/(.*?)\+(.*?)\+(.*)\n\+(.*)/$1+$2 $4+$3/g
A+B+...C\n+D
可能であれば切り替えてくださいA+B D+...C
。