Как преобразовать HHMMSS в HH: MM: SS Unix? - PullRequest
2 голосов
/ 14 февраля 2012

Я попытался преобразовать HHMMSS в HH: MM: SS, и я могу преобразовать его успешно, но мой сценарий занимает 2 часа для завершения из-за размера файла. Есть ли лучший способ (самый быстрый способ) выполнить эту задачу

Data File
data.txt

10,SRI,AA,20091210,8503,ABCXYZ,D,N,TMP,,,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,TMP,,071600,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,TMP,072200,072200,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,TAB,072600,072600,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,TMP,073200,073200,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,TMP,073500,073500,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,MRO,073700,073700,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,CPT,073900,073900,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,TMP,074400,,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TMP,,,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TMP,,090200,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TMP,090900,090900,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TMP,091500,091500,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TAB,091900,091900,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TMP,092500,092500,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TMP,092900,092900,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,MRO,093200,093200,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,CPT,093500,093500,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TMP,094500,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TMP,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,CPT,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,MRO,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TMP,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TMP,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TAB,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TMP,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TMP,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TMP,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TMP,,,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TMP,,170100,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,CPT,170400,170400,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,MRO,170700,170700,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TMP,171000,171000,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TMP,171500,171500,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TAB,171900,171900,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TMP,172500,172500,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TMP,172900,172900,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TMP,173500,173500,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TMP,174100,,

Мой код: script.sh

#!/bin/bash
awk -F"," '{print $5}' Data.txt > tmp.txt # print first line first string before , to tmp.txt i.e. all Numbers will be placed into tmp.txt
sort tmp.txt | uniq -d > Uniqe_number.txt # unique values be stored to Uniqe_number.txt
rm tmp.txt # removes tmp file
while read line; do
echo $line
cat Data.txt | grep ",$line," > Numbers/All/$line.txt # grep Number and creats files induvidtually
awk -F"," '{print $5","$4","$7","$8","$9","$10","$11}' Numbers/All/$line.txt > Numbers/All/tmp_$line.txt
mv Numbers/All/tmp_$line.txt Numbers/Final/Final_$line.txt
done < Uniqe_number.txt
ls Numbers/Final > files.txt
dos2unix files.txt
bash time_replace.sh    

при выполнении вышеупомянутого скрипта он вызовет скрипт time_replace.sh

Мой код для time_replace.sh

#!/bin/bash
for i in `cat files.txt`
do
while read aline
do
TimeDep=`echo $aline | awk -F"," '{print $6}'`
#echo $TimeDep
finalTimeDep=`echo $TimeDep | awk '{for(i=1;i<=length($0);i+=2){printf("%s:",substr($0,i,2))}}'|awk '{sub(/:$/,"")};1'`
#echo $finalTimeDep
##########
TimeAri=`echo $aline | awk -F"," '{print $7}'`
#echo $TimeAri
finalTimeAri=`echo $TimeAri | awk '{for(i=1;i<=length($0);i+=2){printf("%s:",substr($0,i,2))}}'|awk '{sub(/:$/,"")};1'`
#echo $finalTimeAri
sed -i 's/',$TimeDep'/',$finalTimeDep'/g' Numbers/Final/$i
sed -i 's/',$TimeAri'/',$finalTimeAri'/g' Numbers/Final/$i
############################
done < Numbers/Final/$i
done

Есть ли лучшее решение?

Ценю любую помощь.

Спасибо Шри

Ответы [ 3 ]

1 голос
/ 14 февраля 2012

Если существует большое количество файлов, то конвейеры, вероятно, будут влиять на производительность больше, чем что-либо еще - хотя процессы могут быть дешевыми, если вы выполняете огромное количество обработки, то сокращаете количество времени Вы передаете данные через конвейер, можете получить дивиденды.

Так что вам, вероятно, будет лучше написать весь скрипт на awk (или perl). Например, awk может отправлять вывод в произвольный файл, поэтому while lop в вашем первом файле можно заменить на скрипт awk, который делает это. Вам также не нужно использовать временный файл.

Я предполагаю, что сортировка предназначена только для отслеживания прогресса, поскольку вы знаете, сколько существует чисел. Но если вам не нужна сортировка, вы можете просто сделать это:

#!/bin/sh
awk -F ',' '
{
    print $5","$4","$7","$8","$9","$10","$11 > Numbers/Final/Final_$line.txt
}' datafile.txt
ls Numbers/Final > files.txt

В качестве альтернативы, если вам нужно выполнить сортировку, вы можете сделать sort -t, -k5,4,10 (или любое другое поле, в котором должны быть ключи сортировки).

Что касается форматирования даты и времени, awk также выполняет функции, так что вы можете получить скрипт awk, который выглядит следующим образом. Это заменит оба ваших сценариев выше при сохранении той же функциональности (по крайней мере, насколько я могу разобрать с помощью быстрого анализа) ... (Примечание! Не проверено, поэтому может содержать ошибки синтаксиса vauge):

#!/usr/bin/awk
BEGIN {
    FS=","
}
function formattime (t)
{
    return substr(t,1,2)":"substr(t,3,2)":"substr(t,5,2)
}
{
    print $5","$4","$7","$8","$9","formattime($10)","formattime($11) > Numbers/Final/Final_$line.txt
}

, который вы можете сохранить, chmod 700 и позвонить напрямую:

dostuff.awk filename

Другие параметры awk включают изменение полей in-situ, поэтому, если вы хотите сохранить весь исходный файл, но с отформатированными датами, вы можете внести изменения в вышеперечисленное. Измените блок print на:

{
    $10=formattime($10)
    $11=formattime($11)
    print $0
}

Если это не делает все, что вам нужно, надеюсь, это даст некоторые идеи, которые помогут код.

0 голосов
/ 14 февраля 2012

В Perl это близко к детской игре:

#!/usr/bin/env perl
use strict;
use warnings;
use English( -no_match_vars );

local($OFS) = ",";
while (<>)
{
    my(@F) = split /,/;
    $F[9]  =~ s/(\d\d)(\d\d)(\d\d)/$1:$2:$3/ if defined $F[9];
    $F[10] =~ s/(\d\d)(\d\d)(\d\d)/$1:$2:$3/ if defined $F[10];
    print @F;
}

Если вы не хотите использовать English, вы можете написать local($,) = ","; вместо этого; он управляет разделителем выходного поля, выбирая запятую. Код читает каждую строку в файле, разбивает ее на запятые, берет последние два поля, считая с нуля, и (если они не пусты) вставляет двоеточия между парами цифр. Я уверен, что решение «Code Golf» будет намного короче, но это почти разборчиво, если вы знаете какой-либо Perl.

Это будет намного быстрее, чем сценарий, не в последнюю очередь потому, что не нужно ничего сортировать, но также потому, что вся обработка выполняется в одном процессе за один проход файла. Запуск нескольких процессов для каждой строки ввода, как в вашем коде, снижает производительность при больших размерах файлов.

Вывод данных образца, который вы дали:

10,SRI,AA,20091210,8503,ABCXYZ,D,N,TMP,,,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,TMP,,07:16:00,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,TMP,07:22:00,07:22:00,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,TAB,07:26:00,07:26:00,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,TMP,07:32:00,07:32:00,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,TMP,07:35:00,07:35:00,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,MRO,07:37:00,07:37:00,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,CPT,07:39:00,07:39:00,
10,SRI,AA,20091210,8503,ABCXYZ,D,N,TMP,07:44:00,,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TMP,,,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TMP,,09:02:00,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TMP,09:09:00,09:09:00,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TMP,09:15:00,09:15:00,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TAB,09:19:00,09:19:00,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TMP,09:25:00,09:25:00,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TMP,09:29:00,09:29:00,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,MRO,09:32:00,09:32:00,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,CPT,09:35:00,09:35:00,
10,SRI,AA,20091210,8505,ABCXYZ,D,N,TMP,09:45:00,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TMP,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,CPT,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,MRO,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TMP,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TMP,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TAB,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TMP,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TMP,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TMP,,,
10,SRI,AA,20091210,8506,ABCXYZ,U,N,TMP,,,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TMP,,17:01:00,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,CPT,17:04:00,17:04:00,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,MRO,17:07:00,17:07:00,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TMP,17:10:00,17:10:00,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TMP,17:15:00,17:15:00,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TAB,17:19:00,17:19:00,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TMP,17:25:00,17:25:00,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TMP,17:29:00,17:29:00,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TMP,17:35:00,17:35:00,
10,SRI,AA,20091210,8510,ABCXYZ,U,N,TMP,17:41:00,,
0 голосов
/ 14 февраля 2012

Непонятно, для чего нужна вся ваша сортировка и удаление.Я предполагаю, что ваш файл данных имеет только одну запись на строку, и вам нужно изменить 10-е и 11-е поля, разделенные запятыми, с ЧЧММСС на ЧЧ: ММ: СС.

while IFS=, read -a line ; do
    echo -n ${line[0]},${line[1]},${line[2]},${line[3]},
    echo -n ${line[4]},${line[5]},${line[6]},${line[7]},
    echo -n ${line[8]},${line[9]},
    if [ -n "${line[10]}" ]; then
        echo -n ${line[10]:0:2}:${line[10]:2:2}:${line[10]:4:2}
    fi
    echo -n ,
    if [ -n "${line[11]}" ]; then
        echo -n ${line[11]:0:2}:${line[11]:2:2}:${line[11]:4:2}
    fi
    echo ""
done < data.txt

Оперативная часть${variable:offset:length} конструкция, позволяющая извлекать подстроки из переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...