web-dev-qa-db-ja.com

sedを使用して、2回目ごとに「検索と置換」を使用します

+1000 .datファイルのあるフォルダーがあります。また、各ファイルには次のタイプの行が多数含まれています。

-0.0999999999999659-0.0000000006287859
-0.08999999999997500.8000000006183942
-0.0799999999999841-0.0000000007463807
-0.06999999999999320.0000000008661516
-0.06000000000000230.0000000008640644
-0.05000000000001140.0000000008807621
-0.0400000000000205-0.7000000009575896
-0.02999999999997270.0000000009476864
-0.01999999999998180.0000000009150902
-0.00999999999999090.0000000008144152
0.00000000000000000.0000000007097434
0.00999999999999090.0000000007847500
0.01999999999998180.0000000009030998
0.03000000000002960.0000000009741985

これを変換したいすべてのファイルについて

-0.0999999999999659    -0.0000000006287859
-0.0899999999999750    0.8000000006183942
-0.0799999999999841    -0.0000000007463807
-0.0699999999999932    0.0000000008661516
-0.0600000000000023    0.0000000008640644
-0.0500000000000114    0.0000000008807621
-0.0400000000000205    -0.7000000009575896
-0.0299999999999727    0.0000000009476864
-0.0199999999999818    0.0000000009150902
-0.0099999999999909    0.0000000008144152
0.0000000000000000    0.0000000007097434
0.0099999999999909    0.0000000007847500
0.0199999999999818    0.0000000009030998
0.0300000000000296    0.0000000009741985

これらのすべてのファイルで一貫している唯一のものは、2番目の数値(各行の2番目のドットに対応)が常に1.0より小さく、-1.0より大きいことです。ただし、最初の数値は実際の値を取ることができます。

したがって、次のように2番目の「ドット」に「検索と置換」onlyを使用することを考えました。見つける:

0.

と置換する:

   0.

各行の「2番目のドット」にのみ作用するようにsedを指定する方法がわかりません。誰もこれを行う方法について良い考えを持っていますか?

4
Hunter
 sed -E s'/(.*[^-])(-?0\.)/\1    \2/' 999.dat

*は貪欲で、できるだけ多くの文字を消費するため、\.は常に行の最後の1つと一致します。 [^-]は、2番目の番号のオプションの-が2番目のグループに入るようにします。

5
Florian Diesch

2番目の出現のみを置き換えるには、2修飾子を使用します。副<文>この[前述の事実の]結果として、それ故に、従って、だから◆【同】consequently; therefore <文>このような方法で、このようにして、こんなふうに、上に述べたように◆【同】in this manner <文>そのような程度まで<文> AひいてはB◆【用法】A and thus B <文>例えば◆【同】for example; as an example:

$ sed -E 's/-?[[:digit:]][.]/    &/2' file.dat
-0.0999999999999659    -0.0000000006287859
-0.0899999999999750    0.8000000006183942
-0.0799999999999841    -0.0000000007463807
-0.0699999999999932    0.0000000008661516
-0.0600000000000023    0.0000000008640644
-0.0500000000000114    0.0000000008807621
-0.0400000000000205    -0.7000000009575896
-0.0299999999999727    0.0000000009476864
-0.0199999999999818    0.0000000009150902
-0.0099999999999909    0.0000000008144152
0.0000000000000000    0.0000000007097434
0.0099999999999909    0.0000000007847500
0.0199999999999818    0.0000000009030998
0.0300000000000296    0.0000000009741985

使い方:

  • -E

    これは、sedに使用された拡張正規表現を伝えます。これにより、?をエスケープする必要がなくなります。

  • s/-?[[:digit:]][.]/ &/2

    これにより、オプションの-の後に数字が続き、その後にリテラル.が続きます。置換テキストでは、&で示される一致文字列の前に4つのスペースが追加されます。

    代替コマンドの最後の修飾子2は、パターンの2番目の出現のみを置換するようにsedに指示します。

関連する例

異なる置換を行う方法を示すいくつかの例:

$ echo aaaa | sed 's/a/A/1'
Aaaa
$ echo aaaa | sed 's/a/A/2'
aAaa
$ echo aaaa | sed 's/a/A/3'
aaAa
$ echo aaaa | sed 's/a/A/4'
aaaA
$ echo aaaa | sed 's/a/A/g'
AAAA
5
John1024

最初のドットを見つける:)

sed -r 's/(.*\.[^-\.]*)(-?)0\.(.*)/\1\t\20.\3/' file

ノート

  • -r EREを使用
  • s/old/newoldnewに置き換えます
  • (some chars)保存some chars後で参照するために
  • .*任意の数の任意の文字
  • \.リテラル.
  • [^-\.]ハイフンまたは.を除く任意の文字
  • -?オプション-
  • \1\t\20.\3保存されたパターン、タブ、および0.を正しい場所に印刷します
2
Zanna

どう?

$ sed -E 's/(-?0\.[0-9]+)(-?0\.[0-9]+)/\1\t\2/' file
-0.0999999999999659     -0.0000000006287859
-0.0899999999999750     0.8000000006183942
-0.0799999999999841     -0.0000000007463807
-0.0699999999999932     0.0000000008661516
-0.0600000000000023     0.0000000008640644
-0.0500000000000114     0.0000000008807621
-0.0400000000000205     -0.7000000009575896
-0.0299999999999727     0.0000000009476864
-0.0199999999999818     0.0000000009150902
-0.0099999999999909     0.0000000008144152
0.0000000000000000      0.0000000007097434
0.0099999999999909      0.0000000007847500
0.0199999999999818      0.0000000009030998
0.0300000000000296      0.0000000009741985

使い方:

  • -?0\.[0-9]+一致0.の後に1つ以上の他の10進数が続き、オプションで-が前に付きます
  • (-?0\.[0-9]+)(-?0\.[0-9]+)は、上記の2つのインスタンスをキャプチャします
  • \1\t\2は、間にタブを挿入して戻します
2
steeldriver