2016-04-25 19 views
1

の複数の値を置き換えます1場合 。 then 22 2の場合;次に35 3の場合;は、私はcsvファイルを持っているcsvファイル

awk -F , -v OFS=, '{if ($3=="1") $3="22";if ($3=="2") $3="35";if ($3=="3") $3="14"} {print "\""$1"\""",""\""$2"\""",""\""$3"\""",""\""$4"\""}' /tmp/test.csv 

は、それは、Debian上ではなく、Ubuntuの上でうまく動作します。その後、14

これは私が作ったものです。 問題は何ですか?おかげであなた

[EDIT] 例で私はこの1つで昨日引用し、それは動作しますが、ない: 猫-vのtest.CSV

1,1,1,2 
2,2,1,2 
3,3,1,2 
4,4,1,2 
5,5,1,2 
6,6,1,2 
7,7,1,2 
8,8,1,2 
9,9,1,2 
10,10,1,2 
11,11,1,2 
12,12,1,2 
13,13,1,2 
14,14,1,2 
15,15,1,2 
16,16,1,2 
17,17,1,2 
18,18,1,2 
19,19,1,2 
20,20,1,2 
21,21,1,2 
22,22,1,2 
23,23,1,2 
24,24,1,2 
25,25,1,2 
26,26,1,2 
27,27,1,2 
28,28,1,2 
29,29,1,2 
30,30,1,2 
31,31,1,2 
32,32,1,2 
33,33,1,2 
34,34,1,2 
35,35,1,2 
36,36,1,2 
37,37,1,2 
38,38,1,2 
39,39,1,2 
40,40,1,2 

そして今、コマンドリターン:

awk -F , -v OFS=, '{if ($3=="1") $3="2";if ($3=="2") $3="3";if ($3=="3") $3="5"} {print "\""$1"\""",""\""$2"\""",""\""$3"\""",""\""$4"\""}' toast.csv 
"1","1","5","2" 
"2","2","5","2" 
"3","3","5","2" 
"4","4","5","2" 
"5","5","5","2" 
"6","6","5","2" 
"7","7","5","2" 
"8","8","5","2" 
"9","9","5","2" 
"10","10","5","2" 
"11","11","5","2" 
"12","12","5","2" 
"13","13","5","2" 
"14","14","5","2" 
"15","15","5","2" 
"16","16","5","2" 
"17","17","5","2" 
"18","18","5","2" 
"19","19","5","2" 
"20","20","5","2" 
"21","21","5","2" 
"22","22","5","2" 
"23","23","5","2" 
"24","24","5","2" 
"25","25","5","2" 
"26","26","5","2" 
"27","27","5","2" 
"28","28","5","2" 
"29","29","5","2" 
"30","30","5","2" 
"31","31","5","2" 
"32","32","5","2" 
"33","33","5","2" 
"34","34","5","2" 
"35","35","5","2" 
"36","36","5","2" 
"37","37","5","2" 
"38","38","5","2" 
"39","39","5","2" 
"40","40","5","2" 

すべての3番目の値は2ではなく5になります。Debianでこの例と同じ問題が発生します。

+0

のコマンドを実行します。間違いなく、それは私がスクリプトに入れたものとは異なるフィールド(3番目)を返します。私は現在、私のコンピュータにアクセスすることができないので、正しい出力を表示することはできません。 – Kamiz

+0

私はちょうど仮想マシンにUbuntuをインストールしていて、問題はありません...とにかく、明日のコマンドの出力を投稿します。 – Kamiz

+0

こんにちは、私は私の質問を変更しました。 – Kamiz

答えて

1

いずれも、他のマシン対任意のマシンで異なる動作をしません。あなたがしたことを言って間違ったコードを最初に投稿すると、赤ちゃんだった、あなたはバグのコードを持って、それだけです。

あなたは、最新の編集で追加したコードは言う:

if ($3=="1") $3="2";if ($3=="2") $3="3";if ($3=="3") $3="5" 

は、それでは、あなたが値を持っている、あなたの入力ファイルの$ 3で始めるとしましょう1.あなたの最初のテスト/割り当てがif ($3=="1") $3="2"ので、後のコードが実行されます$ 3の値は2です。今度は2回目のテスト/割り当てはif ($3=="2") $3="3"です。最初のコードセグメントが実行された後、$ 3は2になりますので、今度は3に設定されます。だから$ 3を与えられたら$ 3を2に設定し、それを3に設定して5に設定すると、ネット結果は常に5になります。いくつかの "他" S:

awk -F, -v OFS='","' '{if ($3=="1") $3="2"; else if ($3=="2") $3="3"; else if ($3=="3") $3="5"} {print "\""$0"\""}' toast.csv 

、より慣用的なアプローチ使用することを検討してください:

$ cat file 
9,9,1,2 
10,10,2,2 
13,13,3,2 

$ awk -F, -v OFS='","' 'BEGIN{split("2,3,5",m)} {$3=m[$3]} {print "\""$0"\""}' file 
"9","9","2","2" 
"10","10","3","2" 
"13","13","5","2" 

if ($3=="1") $3="2"; else if ($3=="2") $3="3"; else if ($3=="3") $3="5" 

が、少なくとも、個別に各フィールドを印刷することを避けるためにスクリプトを変更しますあなたの$ 3は、あなたが表示/テストする値の一つです。簡単な調整がない場合は、

$ awk -F, -v OFS='","' 'BEGIN{split("1,2,3",a); split("2,3,5",b); for (i in a) m[a[i]]=b[i]} {$3=($3 in m ? m[$3] : $3)} {print "\""$0"\""}' file 
"9","9","2","2" 
"10","10","3","2" 
"13","13","5","2" 

またはあなたが好む場合:別の任意の数の1セットをマッピングし、マッピングされた取得する必要はありませんいくつかの入力データを可能にするために一般的に

$ awk -F, -v OFS='","' 'BEGIN{split("1,2,2,3,3,5",t); for (i=2;i in t;i+=2) m[t[i-1]]=t[i]} {$3=($3 in m ? m[$3] : $3)} {print "\""$0"\""}' file 
"9","9","2","2" 
"10","10","3","2" 
"13","13","5","2" 
+1

詳細な回答ありがとうございました! – Kamiz

0

のsedでそれは簡単に次のようになります。

sed 's/\([0-9]*,[0-9]*,\)1\(,[0-9]*\)/\122\2/' /tmp/test.csv 
sed 's/\([0-9]*,[0-9]*,\)2\(,[0-9]*\)/\135\2/' /tmp/test.csv 
sed 's/\([0-9]*,[0-9]*,\)3\(,[0-9]*\)/\114\2/' /tmp/test.csv 

私はそれがトリックと最もSH/bashの環境になります最も可能性の高い作業を行う必要があると考えています。

EDIT: 実際に何かを変更する前に何が起こるかを知るために、これは各コマンドが実際に行う置換を表示していることに注意してください。あなたは、まず、あなたのファイルをバックアップし、-iフラグでインプレース交換を行うことをお勧めします:あなたが投稿したコードの

$ cat /tmp/test.csv 
1,1,1,2 
2,2,1,2 
3,3,1,2 
4,4,1,2 
5,5,1,2 
6,6,1,2 
7,7,1,2 
8,8,1,2 
9,9,1,2 
10,10,2,2 
11,11,2,2 
12,12,2,2 
13,13,3,2 
$ cp /tmp/test.csv /tmp/test.csv.bak 
$ sed -i 's/\([0-9]*,[0-9]*,\)1\(,[0-9]*\)/\122\2/' /tmp/test.csv 
$ sed -i 's/\([0-9]*,[0-9]*,\)2\(,[0-9]*\)/\135\2/' /tmp/test.csv 
$ sed -i 's/\([0-9]*,[0-9]*,\)3\(,[0-9]*\)/\114\2/' /tmp/test.csv 
$ cat /tmp/test.csv 
1,1,22,2 
2,2,22,2 
3,3,22,2 
4,4,22,2 
5,5,22,2 
6,6,22,2 
7,7,22,2 
8,8,22,2 
9,9,22,2 
10,10,35,2 
11,11,35,2 
12,12,35,2 
13,13,14,2 
+2

いいえ、sedでは簡単ではありませんが、3つのスクリプト(希望の出力btwを生成しません)で示されるように、より複雑で効率的ではありません。 –

+0

@Edモートン、少年の誰かがパンティーで目が覚めた。申し訳ありませんが、ソリューションが気に入らないのですが、それは仕事を完了させ、ちょうどあらゆるbash環境で動作するはずです。 – Mikel

+1

何も書かれていないので、期待される出力が得られません(すべてのフィールドの前後に二重引用符がありません)。awkよりもsedのほうが簡単だと言っても間違いです。あなたのsedスクリプトが何の役目を果たすかをawkスクリプトを使って書く方法の1つは、単にawkです。BEGIN {FS = OFS = "、"; split( "22,35,14"、m)} {$ 3 = m [$ 3]} 1 'file'あなたは入力ファイルの1回のパスですべての置換を行うために一度呼び出すだけですが、望ましい出力とより重要なことは、OPの質問に対処していない。 –

関連する問題