sed、前後に検索して配置

sed、前後に検索して配置

日付と時刻が異なるテキストが多すぎてパターンとして使用できないのですが、最初と,印刷後"、2番目,と印刷前を検索できるかどうか疑問に思います"。次のようにする必要があります。

4,"2014-05-08 18:22:24",14718202,4,184
4,"2014-05-09 22:07:11",1278184,4,221
3,"2014-05-05 10:01:24",1238461,1,222

これで、次のようになります。

4,2014-05-08 18:22:24,14718202,4,184
4,2014-05-09 22:07:11,1278184,4,221
3,2014-05-05 10:01:24,1238461,1,222

よろしくお願いします。

答え1

非常に簡単な方法は、私が言ったように、最初と2番目のコンマを置き換えることです。

sed 's/,/,"/;s/,/",/2' infile

日付を一致させる必要がない場合(すべての行の形式が同じであると仮定):

sed 's/\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\ [0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\)/"&"/' infile

または、最初と2番目のカンマの間のすべての内容:

sed 's/^\([^,]*,\)\([^,]*\)\(,.*\)/\1"\2"\3/' infile

答え2

日付/時刻フィールドを参照したいとおっしゃいましたか?

awk 'BEGIN {FS=OFS=","} $2="\""$2"\""' infile > outfile 

答え3

他の方法:

sed 's/,\([^,]*\),/,"\1",/' <infile >outfile

少なくとも2つのカンマがない行では機能しません。したがって、少なくとも2つのカンマのない行は完全にスキップされます。デフォルトの正規表現パターンは以下に基づいているため、常に最初の2つのカンマのみを取得します。左が一番長いです。ルール - つまり、ゲームは常に次のようになります。まもなくできるだけ、できるだけ長いできるだけたくさん。つまり、1行で見つかった最初のカンマは、私たちが探している最初のコンマを満たし、次のコンマは常にその間の非カンマの文字の最長の順序に従います。

sed 's/,\([^,]*\),/,"\1",/
' <<\IN
4,2014-05-08 18:22:24,14718202,4,184
4,2014-05-09 22:07:11,1278184,4,221
3,2014-05-05 10:01:24,1238461,1,222
IN

最初のコンマと一致し、その後に[^,]*ゼロ個以上の非カンマ文字*が続き、その後にカンマが続きます。非カンマ一致をサブ式にグループ化し、最初の項目を逆参照します。[^,]*\(\)\1(ここのみ)置換ドアの右側にある置換フィールドの一致グループs///。カンマ,"はカンマと引用符、引用符と",コンマで直接置き換えられますが、逆参照グループは自分で置き換えられます。だから...

出力

4,"2014-05-08 18:22:24",14718202,4,184
4,"2014-05-09 22:07:11",1278184,4,221
3,"2014-05-05 10:01:24",1238461,1,222

それともできます...

sed '/,.*,/s/[^,]*/"&"/2' <infile >outfile

これはs///置換を条件付きにします。ここで使用される置換は、単一のコンマに一致する行にのみ適用できるためです。この場合、そのコンマを除くすべての項目を引用します。少なくとも 2 つのコンマに一致する行にのみ置換が適用されるようにするには、少なくとも 1 つのカンマと/,.*,/そのあとにすべての* .タイプのゼロ文字以上と少なくとも 1 つのコンマが一致する行のみを明示的に処理し、その行でのみ次をs///使用します。します。 2cdはカンマ[^,]*ではなくゼロ以上を置き換えるために一致し*、それ自体は引用符で囲まれています&"

行の最初の文字がコンマであっても、まだ正しいフィールドを取得します。例:

sed '/,.*,/s/[^,]*/"&"/2' <<\IN
,2014-05-05 10:01:24,1238461,1,222
IN

...印刷...

,"2014-05-05 10:01:24",1238461,1,222

...0 個以上の非カンマ文字の最初の一致は、最初のカンマの前に表示される長さがゼロの文字列であるためです。

答え4

方法は次のとおりですsed

$ sed -n 's/\(\([0-9]\|-\)* \([0-9]\|:\)*\)/\"\1\"/p' file.txt
4,"2014-05-08 18:22:24",14718202,4,184
4,"2014-05-09 22:07:11",1278184,4,221
3,"2014-05-05 10:01:24",1238461,1,222

これはまた働きます:

sed -n 's/\(.* \([0-9]\|:\)*\)/\"\1\"/p' file.txt

関連情報