2017-03-01 34 views
1

在HDFS我的文件夾路徑結構是這樣的:合併多個文件遞歸HDFS

/data/topicname/year=2017/month=02/day=28/hour=00 
/data/topicname/year=2017/month=02/day=28/hour=01 
/data/topicname/year=2017/month=02/day=28/hour=02 
/data/topicname/year=2017/month=02/day=28/hour=03 

這些路徑裏面我有很多小規模的JSON文件。我正在編寫一個shell腳本,它可以將所有這些單獨目錄中存在的所有文件合併爲一個單獨的文件名,具體取決於路徑。

例子:

內的所有JSONs /數據/ topicname /年= 2017 /月= 02 /天= 28 /小時= 00成一個合併的文件full_2017_02_28_00.json

所有JSONs /數據/所有JSONs在/ data/topicname/year = 2017/month = 02/day = 28/hour = 2/day = 28/hour = 01到一個合併文件full_2017_02_28_01.json

02合併到一個合併文件full_2017_02_28_02.json中,依此類推。

在上述模式中保留文件名是我將嘗試實現的第二職業。目前我可以對文件名進行硬編碼。

但是,目錄路徑結構內部的遞歸串聯沒有發生。

到目前爲止,我在下面嘗試:

hadoop fs -cat /data/topicname/year=2017/* | hadoop fs -put - /merged/test1.json 

錯誤: -

cat: `/data/topicname/year=2017/month=02/day=28/hour=00': Is a directory 
cat: `/data/topicname/year=2017/month=02/day=28/hour=01': Is a directory 
cat: `/data/topicname/year=2017/month=02/day=28/hour=02': Is a directory 

遞歸貓是不會發生在上述嘗試

hadoop fs -ls /data/topicname/year=2017/month=02 | find /data/topicname/year=2017/month=02/day=28 -name '*.json' -exec cat {} \; > output.json 

錯誤: -

find: ‘/data/topicname/year=2017/month=02/day=28’: No such file or directory 

這是在做本地FS而不是HDFS發現上面嘗試

for i in `hadoop fs -ls -R /data/topicname/year=2017/ | cut -d' ' -f19` ;do `hadoop fs -cat $i/* |hadoop fs -put - /merged/output.json`; done 

錯誤: -

cannot write output to stream message is repeated multiple times 
file /merged/output.json is repeated a few times 

這是如何實現的?我不想使用Spark。

回答

0

使用-appendToFile

for file in `hdfs dfs -ls -R /src_folder | awk '$2!="-" {print $8}'`; do hdfs dfs -cat $file | hdfs dfs -appendToFile - /target_folder/filename;done 

所需的時間將取決於文件的數量和大小的過程是連續的。

+0

這是服用大量的時間。它運行了20分鐘,並且只能附加10-15個合併文件大小爲5MB的文件 – earl

+0

是的,使用fsshell是連續的,速度會很慢。此解決方案是您發佈的問題的語法正確版本。爲了實現並行性,請使用MapReduce或Spark(您提到過,因爲不想使用)。 – franklinsijo

0

我能夠實現我的目標,下面的腳本:

#!/bin/bash 

for k in 01 02 03 04 05 06 07 08 09 10 11 12 
do 
     for j in 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 
     do 
       for i in 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 
       do 

       hadoop fs -cat /data/topicname/year=2017/month=$k/day=$j/hour=$i/* | hadoop fs -put - /merged/TEST1/2017"_"$k"_"$j"_"$i.json 
       hadoop fs -du -s /merged/TEST1/2017"_"$k"_"$j"_"$i.json > /home/test/sizetest.txt 
       x=`awk '{ print $1 }' /home/test/sizetest.txt` 
       echo $x 
       if [ $x -eq 0 ] 
       then 
       hadoop fs -rm /merged/TEST1/2017"_"$k"_"$j"_"$i.json 
       else 
       echo "MERGE DONE!!! All files generated at hour $i of $j-$k-2017 merged into one" 
       echo "DELETED 0 SIZED FILES!!!!" 
       fi 

       done 
     done 
done 

rm -f /home/test/sizetest.txt 
hadoop fs -rm -r /data/topicname