1

この一見単純な質問で申し訳ありませんが、どこでも解決策を見つけようとして、さまざまな sed オプションを試すのに時間がかかりすぎました。テキスト ファイル内のすべてのドットをコンマに置き換える必要があるだけですが、2 つの位置の間だけです。例として、以下から:

1.3.5.7.9

1.3,5,7.9

ということで、交換。by 、位置 3 から 7 の間。ありがとう!

編集: 申し訳ありませんが、問題を単純化するふりをしましたが、質問に詳細が不足しているため、最初の 3 つの回答はどれも機能しないため、もう少し詳しく説明します。重要な点は、文字列の残りの部分を知らなくても、位置の間隔ですべてのドットをコンマに置き換えることです。

Here some text. I don't want to change. 10.000 usd  234.566 usd Continuation text.
More text. No need to change this part.    345 usd   76.433 usd Text going on. So on.

これは列単位の固定幅のテキスト ファイルで、数字の国際形式を変更して、ドットをコンマに置き換える必要があります。検索して最終的にドットを置き換える必要がある最初と最後の位置を知っているだけです。明らかに、すべての図にドットがあるわけではありません (1000 を超えるもののみ)。ありがとう。

4

5 に答える 5

2

質問を明確にした後、回答を書き直します。

sedこれだけで処理するのは困難ですが、cutや などの他の標準ユーティリティを使用すると簡単に処理できpasteます。

$ start=40
$ end=64
$ paste -d' ' <(cut -c -$((start-1)) example.txt) \
> <(cut -c $((start+1))-$((end-1)) example.txt | sed 'y/./,/') \
> <(cut -c $((end+1))- example.txt)
Here some text. I don't want to change. 10,000 usd  234,566 usd Continuation text.
More text. No need to change this part.    345 usd   76,433 usd Text going on. So on.

>前の行の継続を意味するだけです。<本当です)。もちろん、これは非常に非効率的ですが、概念的には単純です。

余分なスペースを取り除くために、すべての+1andを使用しました。-1必要かどうかわかりません。

純粋な sed ソリューション (自分自身を引き締めます):

$ sed "s/\(.\{${start}\}\)\(.\{$((end-start))\}\)/\1\n\2\n/;h;s/.*\n\(.*\)\n.*/\1/;y/./,/;G;s/^\(.*\)\n\(.*\)\n\(.*\)\n\(.*\)$/\2\1\4/" example.txt
Here some text. I don't want to change. 10,000 usd  234,566 usd Continuation text.
More text. No need to change this part.    345 usd   76,433 usd Text going on. So on.

GNU sed:

$ sed -r "s/(.{${start}})(.{$((end-start))})/\1\n\2\n/;h;s/.*\n(.*)\n.*/\1/;y/./,/;G;s/^(.*)\n(.*)\n(.*)\n(.*)$/\2\1\4/" example.txt 
Here some text. I don't want to change. 10,000 usd  234,566 usd Continuation text.
More text. No need to change this part.    345 usd   76,433 usd Text going on. So on.
于 2013-02-04T18:19:15.627 に答える
1
$ echo "1.3.5.7.9" |
gawk -v s=3 -v e=7 '{
   print substr($0,1,s-1) gensub(/\./,",","g",substr($0,s,e-s+1)) substr($0,e+1)
}'
1.3,5,7.9
于 2013-02-04T19:17:42.437 に答える
1


正規表現を単純化しようとしていますが、より寛容です。

echo 1.3.5.7.9 | sed -r "s/^(...).(.).(..)/\1,\2,\3/"
1.3,5,7.9

PS: BSD sed では動作しません。

于 2013-02-04T19:08:02.793 に答える
1

これを pure で行うのはかなり厄介ですsed。に厳密に制約されていない場合はsed、別のツールを使用してこれを行うことをお勧めします。Ed Morton のgawkベースのソリューションは、おそらく、これを解決するための最も厄介でない (しゃれを意図していない) 方法です。

以下は、単調な作業を行うために使用する例ですsedが、簡単にするために bash 関数にラップされています。

function transform () {
    line=$1
    start=$2
    end=$3
    # Save beginning and end of line
    front=$(echo $line | sed -e "s/\(^.\{$start\}\).*$/\1/")
    back=$(echo $line | sed -e "s/^.\{$end\}//")
    # Translate characters
    line=$(echo $line | sed -e 'y/\./,/')
    # Restore unmodified beginning/end
    echo $line | sed -e "s/^.\{$start\}/$front/" -e "s/\(^.\{$end\}\).*$/\1$back/"
}

この関数を次のように呼び出します。

$ transform "1.3.5.7.9" 3 7
1.3,5,7.9
于 2013-02-05T23:45:33.567 に答える
0

皆さん、ありがとうございました。簡単な解決策として私が見つけたもの(私のメリットではありません)は次のとおりです。

  1. 固定幅ファイルの場合:

    awk -F "" 'OFS="";{for (j=2;j<= 5;j++) if ($j==".") $j=","}'1
    

2 番目から 5 番目までのすべてのドットをカンマに変更します。

  1. タブ区切りフィールド ファイルの場合:

    awk -F'\t' 'OFS="\t" {for (j=2;j<=5;j++) gsub(/\./,",",$j)}'1
    

2 番目のフィールドから 5 番目のフィールドまでのすべてのドットをコマに変更します。

それが誰かを助けることができることを願っています: 最初はとても大変だとは想像できませんでした.

于 2013-02-06T09:23:22.043 に答える