1. 程式人生 > >Hadoop去掉格,換行符,製表符,回車符,換頁符【好吧,其實用正則表示式一下子就搞定了】

Hadoop去掉格,換行符,製表符,回車符,換頁符【好吧,其實用正則表示式一下子就搞定了】

第一步:將文件中的空格,換行符(\n),製表符(\t),回車符(\n),換頁符(\f)去掉

這時候可以採用兩種方法

1.使用Hadoop將文字以預設的分隔符(空格,換行符,製表符,回車符,換頁符)進行分割,並將分割後的字串直接輸出,這樣子新的文件中將不包括這些分隔符。

/**
 這裡在Map中去除空格、tab、回車等
 */
import java.io.*;
import java.io.IOException;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;

public class Standardization {

  public static class TokenizerMapper
       extends Mapper<Object, Text, Text, IntWritable>{

    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();

    public void map(Object key, Text value, Context context
                    ) throws IOException, InterruptedException {
                        //預設的分隔符是“空格”、“製表符(‘\t’)”、“換行符(‘\n’)”、“回車符(‘\r’)”,換頁(‘\f’)
      StringTokenizer itr = new StringTokenizer(value.toString());
      while (itr.hasMoreTokens()) {
        word.set(itr.nextToken());
                context.write(word, one);//將分隔分割成功的文字直接輸出就排除了這些分隔符
      }
    }
  }

  public static class IntSumReducer
       extends Reducer<Text,IntWritable,Text,IntWritable> {
    private IntWritable result = new IntWritable(1);

    public void reduce(Text key, Iterable<IntWritable> values,
                       Context context
                       ) throws IOException, InterruptedException {
                                PrintWriter outputStream=null;//這個被建立的檔案將在jar所在目錄下生成,而不會在存在於dfs
                                try{
                                        outputStream =new PrintWriter(new FileOutputStream("out.txt",true));
                }
                                catch(FileNotFoundException e){
                                        System.out.println("沒有許可權");
                                        System.exit(0);
                                        }
                outputStream.print(key.toString());
                outputStream.close();
                context.write(key,result);//而這裡的內容將被解除安裝dfs上
    }
  }

  public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
    if (otherArgs.length < 2) {
      System.err.println("Usage: wordcount <in> [<in>...] <out>");
      System.exit(2);
    }
    Job job = new Job(conf, "word count");
    job.setJarByClass(Standardization.class);
    job.setMapperClass(TokenizerMapper.class);
    //這裡並沒有配置shuffle
    job.setReducerClass(IntSumReducer.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
    for (int i = 0; i < otherArgs.length - 1; ++i) {
      FileInputFormat.addInputPath(job, new Path(otherArgs[i]));
    }
    FileOutputFormat.setOutputPath(job,
      new Path(otherArgs[otherArgs.length - 1]));
    System.exit(job.waitForCompletion(true) ? 0 : 1);
  }
}

以上程式碼可以執行並得到所需結果,但有一個缺點是會將輸入檔案中的文字的順序打亂即輸出檔案中的文字順序和輸入檔案的不同。

這是由於在shuffle過程中對map的輸出 重新進行了排序,如果是英文的話是按照a-z的字母表順序。、



另外執行hadoop程式可藉助shell程式設計,減少重複敲程式碼。而shell中的內容直接寫命令即可。