カンマの前のすべての行に 9 文字が含まれるまで前にゼロを追加し、sed を使用して 3 桁ごとに 1 文字を挿入します。

カンマの前のすべての行に 9 文字が含まれるまで前にゼロを追加し、sed を使用して 3 桁ごとに 1 文字を挿入します。

目的は、カンマの前のすべての行に9文字が含まれるまで前に0を追加してから、3番目の数字ごとに文字を挿入することですsed

入力する

12345,1s4c3v6s3nh6
123456789,9h5vgbdx34dc
12,7h4f45dcvbgh
1234567,09klijnmh563

現在の結果

[vagrant@localhost ~]$ sed -e 's/\([0-9]\{3\}\),/\/\1\//g' file
12/345/1s4c3v6s3nh6
123456/789/9h5vgbdx34dc
12,7h4f45dcvbgh
1234/567/09klijnmh563

予想される結果

000/012/345,1s4c3v6s3nh6
123/456/789,9h5vgbdx34dc
000/000/012,7h4f45dcvbgh
001/234/567,09klijnmh563

メモ:

  1. 12345になり00001234512につながるはずです 000000012。つまり、カンマの前の数字の順序に焦点を当てます。
  2. 行の形式は常にです MAX_9_characters,fixed_12_characters。つまり、 1234512345,1s4c3v6s3nh6入力ファイルには存在しません。

問題は、sedを使用して文字数を等しくすることができないことです。これがどのように可能ですか?

答え1

入力の2番目のフィールドに長いシーケンス番号がない場合は、以下を試してください。

$ sed -e 's|^[^,]*|#000000000&|;s|#[^,]*\(.\{9\}\),|\1,|;s|\([0-9]\{3\}\)|\1/|g;s|/\([^0-9]\)|\1|;s|/$||' file
000/012/345,1s4c3v6s3nh6
123/456/789,9h5vgbdx34dc
000/000/012,7h4f45dcvbgh
001/234/567,09klijnmh563

説明する

  • s|^[^,]*|#000000000&|:私たちは最初から最初まですべてを一致させ、,それを製造元とn個の数字0に置き換えます#。ここで、nは私たちが満たすべき長さです。

  • s|#[^,]*\(.\{9\}\),|\1,|:トークンから最初のものまですべてを一致させ、,その前の最後の9文字だけを保持し、残りは,捨てます。

  • s|\([0-9]\{3\}\)|\1/|g/3桁ずつ順に追加します。

  • s|/\([^0-9]\)|\1|;s|/$||:after が/数値でない場合、または/行末にある場合は削除します。

または使いやすいですperl

$ perl -F',' -anle '
    $F[0] = sprintf "%09s", $F[0];
    $F[0] =~ s|.{3}|$&/|g;
    chop $F[0];
    print join ",",@F;
' file
000/012/345,1s4c3v6s3nh6
123/456/789,9h5vgbdx34dc
000/000/012,7h4f45dcvbgh
001/234/567,09klijnmh563

答え2

おそらくこれを行うことができますが、sedこれは私のsed-fuの範囲外です。他の解決策は次のとおりです。

perl -F, -lane '$F[0]=sprintf("%09s",$F[0]);
                $F[0]=~s#(...)(?!$)#$1/#g;
                print "$F[0],$F[1]"' file

-a各入力行をフィールドに分割して配列@Fに保存します。フィールド区切り記号を設定します-F,ここ)。末尾の改行を削除-lし、各呼び出しの末尾に改行を追加してprint入力nファイルを1行ずつ読み込み、指定されたスクリプトを各行-eに適用します。

スクリプト自体は3つのことを行います。まず、最初のフィールドに先行()を追加するために使用されますsprintf。次に、最初のフィールドの3つの文字セットをすべて置き換えます(最後の文字を除く:)/ `。最後に、修正された最初のフィールド、カンマ、および2番目のフィールドを印刷します。0$F[0](?!$) with themselves followed by a

答え3

これで問題が改善されたので、sedGnoucの答えを次のように単純化できます。

sed 's|^|000000000|;s|.*\(...\)\(...\)\(...,\)|\1/\2/\3|' file

または、一般的なソリューションの味を少し維持したい場合

sed 's|^|000000000|;s|.*\(.\{3\}\)\(.\{3\}\)\(.\{3\},\)|\1/\2/\3|' file

少なくとも他の答えの一部と同様に、1行にカンマが1つしかないとします。

関連情報