I have over one million files. And I have to proceed over them.
My files' directory hierarchies just like below
source=/opt/output/renamed/
target=/opt/output/combine
send=/opt/output/send/combined
Firstly I have to loop 1000 files from source (/opt/output/renamed) directory and group them by filename.
Filename ==> ORACLE_gprtcp_201209221454_312312.log.gz
first and second colun is not important so much. But I have to group them by third field which is a timestamp.
And they have to be grouped by thirty minutes. For example,there are two files which like these
1.ORACLE_gprtcp_201209231632_987546.log.gz
2.ORACLE_gprtcp_201209231612_123876.log.gz
3.ORACLE_gprtcp_201209231602_987546.log.gz
4.ORACLE_gprtcp_201209231644_987546.log.gz
5.ORACLE_gprtcp_201209231647_987546.log.gz
6.ORACLE_gprtcp_201209231601_987546.log.gz
the first group's time interval must be in thirty minutes
for example, first goruped files are
2, 3 and 6 files (they are in first thirty minutes) 1,4 and 5 files(they are in last thirty minutes)
I have tried to write a script just like this
#!/bin/bash
sourceFolder="/opt/rename/"
limitCount=10 # Limit for send file count for per process
renamed="/opt/combine"
target="/opt/send/combined/"
for sf in ${sourceFolder}; do
fileList=$(find ${sf} -type f -name "*.gz" | sort -t '_' -k3 | head -${limitCount} )
for filePath in $(echo "${fileList}"); do
fileName=$(basename ${filePath}) # source file name
dirName=$(dirname ${filePath}) # source dir name
#timeRef=$(echo ${fileName} | cut -d '_' -f 3 | sed 's/\(.\{11\}\).*/\1/')
timeRef=$(echo ${fileName} | cut -d '_' -f 3 | cut -c-11)
#time ref : ORACLE_gprtcp_20120923012703_3431593.log.gz
if [ "${sf}" == "/opt/rename/" ]; then ##### combine
#Move files to under /opt/combine/ to process files in the fastest way
mv ${filePath} ${renamed}
timeRef30="${group} | cut -d '_' -f 3 | sed 's/\(.\{10\}\).*/\1/')"
echo $timeRef30
for files in $(find ${renamed} -name "*${timeRef}*" | uniq)
do
fileGroup=$(echo $files | sort -t '_' -k 3 )
first=$(echo ${fileGroup} | head -1 | cut -d '_' -f 4 | cut -d '.' -f 1)
last=$(echo ${fileGroup} | tail -1 | cut -d '_' -f 4 | cut -d '.' -f 1)
for group in ${fileGroup}
do
timeInt=$(echo ${group} | cut -d '_' -f 3 | sed 's/\(.\{10\}\).*/\1/')
zcatBaseName=$(dirname ${group}) #/opt/rename/
zcatName=$(basename ${group})
zcatUniq=$(echo ${group}| cut -d '_' -f 4 | cut -d '.' -f 1)
newName=$(echo ${targetNAT}/ORACLE_gprtcp_${timeInt}000_${first}${last}.log)
sleep 1
echo "starting to zcat all files ${fileGroup}"
zcat -f $(echo ${fileGroup}) >> "/opt/combine/ORACLE_gprtcp_${timeInt}000_${first}${last}.log"
gzip "/opt/infolog/output/iotest/24/combine/ORACLE_gprtcp_${timeInt}000_${first}${last}.log"
rm -f $(echo ${fileGroup})
sleep 4
done
done
fi
done
done
Is there anyone that can give me a suggestion about how can I success to group files between thirty minutes and zcat them to new file ?
Thanks in advance
${group}intimeRef30="${group}..."before you've defined it. Anyway, you probably want to extract the timestamp from the filename (cut -d_ -f3is fine), and then get the last two digits of that, will be 01-30 or 31-59. use that to decide whether to push the filename into a $first array or $last array. hope that helps, it's 00:45 am here now, too late for me to think too hard or long about it. – Craig Sanders Oct 2 '12 at 14:43ORACLE_??????_YYYYmmddHHMM_######.log.gzfiles from the same half hour and zcat those files (in time order, I presume?) to a single file with roughly the same name, but with the time rounded down to a whole half hour and with some extra stuff on the end (you'll have to describe this as well). – jw013 Oct 2 '12 at 14:56