2017-06-08 27 views
-2
200005251|AAAAAA 
200005252|BBBBB 
200005261|CCCCCC 
200005262|DDDDD 
200005292|EEEEEE 
200005301|FFFFFF 
200005302|VVVVVV 
200005311|AAAAAA 
200005312|JJJJJJ 
200006011|LLLLLL 
200006021|SSSSSS 
200006022|HHHHHH 
200006051|OOOOOO 
200006052|GGGGGG 
200006061|KKKKKK 
200006062|FFFFF 
200006071|TTTTTT 

私は上記のように最初のフィールドにファイルを持っています。 2つの行を1つにまとめる必要があります...... 1と...... 2。他の人はそのままにしておいてください。希望出力:条件付きで2行をマージする

200005251|AAAAAA 200005252|BBBBB 
200005261|CCCCCC 200005262|DDDDD  
200005292|EEEEEE 
200005301|FFFFFF 200005302|VVVVVV 
200005311|AAAAAA 200005312|JJJJJJ 
200006011|LLLLLL 
200006021|SSSSSS 200006022|HHHHHH 
200006051|OOOOOO 200006052|GGGGGG 
200006061|KKKKKK 200006062|FFFFF 
200006071|TTTTTT 

ありがとうございます。救助へ

+0

を? – choroba

答えて

0

awkのソリューション:

awk -v RS=" " '{ for(i=1;i<=NF;i++) 
        if ($i~/1$/ && $(i+1)~/2$/) { 
         printf("%s %s\n",$i,$(i+1)); i++; 
        } else { 
         printf("%s\n",$i) 
        } 
       }' file 

出力:あなたはあなたの最初の入力を変更してきたように

200005251 200005252 
200005261 200005262 
200005292 
200005301 200005302 
200005311 200005312 
200006011 
200006021 200006022 
200006051 200006052 
200006061 200006062 
200006071 

- ここ延長だバージョン:

awk -v RS=" " '{ for(i=1;i<=NF;i++) 
        if ($i~/1\|[[:alpha:]]+$/ && $(i+1)~/2\|[[:alpha:]]+$/) { 
         printf("%s %s\n",$i,$(i+1)); i++; 
        } else { 
         printf("%s\n",$i) 
        } 
       }' file 

出力V.2:

200005251|AAAAAA 200005252|BBBBB 
200005261|CCCCCC 200005262|DDDDD 
200005292|EEEEEE 
200005301|FFFFFF 200005302|VVVVVV 
200005311|AAAAAA 200005312|JJJJJJ 
200006011|LLLLLL 
200006021|SSSSSS 200006022|HHHHHH 
200006051|OOOOOO 200006052|GGGGGG 
200006061|KKKKKK 200006062|FFFFF 
200006071|TTTTTT 

詳細

  • -v RS=" " - 代わりに改行

  • for(i=1;i<=NF;i++)のレコードセパレータとしてスペースを扱う - すべてを反復処理フィールド

  • if ($i~/1\|[[:alpha:]]+$/ && $(i+1)~/2\|[[:alpha:]]+$/) - 現在のフィールドが1を持っている場合は、その第一セクションと次のフィールドの最後にチェックするための条件は、その第一セクションの終わりNUMSが付いたファイルである

+0

あなたの助けと親切な説明をありがとう – firefoxix

0

たPerl:

perl -nE 'chomp; 
      if ($previous =~ /1$/ and /2$/) { 
       say "$previous $_"; 
       $previous = ""; 
      } else { 
       say $previous if $previous; 
       $previous = $_; 
      } 
      }{ say $previous if $previous 
     ' -- input 

あなたは以前$の前の行を保持します。 1で終了し、現在の行(-nに格納されている$_に格納されている)の末尾が2で終わる場合は、両方を同じ行に出力し、$ previous;をクリアします。それ以外の場合は、前のものがある場合はそれを表示し、現在のものを$ previousに格納します。最後の行は、前の行で印刷されていない場合は最後の行を出力します。

+0

これは動作しますが、フィールドが1つの場合のみです。私は "|"で区切られた2つのフィールドを持つファイルを持っています – firefoxix

+0

だから、それを修正しようとするか、新しい質問をしてみてください。 – choroba

0
awk '{ num[NR]=$1 } END { for (i=1;i<=NR;i++) if (substr(num[i+1],length(num[i+1]))=="2") { printf num[i]"\t"num[i+1]"\n";i++ } else { print num[i] } }' nums 

2を持っていますデータ。最初にnumという配列にデータを格納し、配列チェックをループして次の要素が2で終わるかどうかを調べます(最後の文字を取得するために長さとともにsubstr関数を使用します)。そうであれば、両方を印刷してカウンタに追加します。それ以外の場合は要素を印刷します。あなたの目標を達成することができる

0

シンプルawkスクリプト、

awk_file:

{ 
    if($1%2==1) { 
    if(odd==1){ 
     printf "\n"; 
    } 
    printf "%s ",$0; 
    odd=1; 
    } else { 
    printf "%s\n",$0; 
    odd=0; 
    } 
} END {printf "\n"} 

次に実行:あなたは試してみましたが、どのようにそれが失敗したのは何

$ awk -v FS='|' -f awk_file file 
200005251|AAAAAA 200005252|BBBBB 
200005261|CCCCCC 200005262|DDDDD 
200005292|EEEEEE 
200005301|FFFFFF 200005302|VVVVVV 
200005311|AAAAAA 200005312|JJJJJJ 
200006011|LLLLLL 
200006021|SSSSSS 200006022|HHHHHH 
200006051|OOOOOO 200006052|GGGGGG 
200006061|KKKKKK 200006062|FFFFF 
200006071|TTTTTT 
+0

これはより良い一般的なアプローチです。あなたは普通の英語でこのコードはどうやって説明できますか? – firefoxix

+0

論理から、抽出された数値が奇数である間に '$ 0 \ n'を出力し、偶数であるときに' $ 0'を出力します。最後に、奇妙なものが抽出された場合は、 '$ 0'の前に' \ n'を追加してください – CWLiu

関連する問題