Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: jansen 15. 11. 2012, 13:13:54
-
Zdravím, jsem nový v prostředí unixu. Snažím se vytvořit skript, který by měl joinovat dva soubory na základě klíče.
jeden soubor obsahuje log v tomto tvaru:
SCR01 14:41
SCR02 14:42
SCR03 14:43
SCR02 14:44
SCR04 14:45
SCR02 14:46
druhý obsahuje mapovací tabulku s popisy - co která činnost znamená např.:
SCR01 login
SCR02 main page
SCR03 left menu
SCR04 1. content
....
potřeboval bych výstup ve tvaru:
SCR01 14:41 login
SCR02 14:42 main page
SCR03 14:43 left menu
SCR02 14:44 main page
SCR04 14:45 1. content
SCR02 14:46 main page
zkoušel jsem příkaz join ale mám za to, že tuto úlohu tím nelze vyřešit...
ještě poznámka k datům:
- jak je vidět v logu je běžně že se úlohy opakují - potřebuji ke každé přiřadit popis i když je stejný
- pokud se nenajde v mapovací tabulce podle klíče popis, chci vypsat klíč a čas bez popisu
díky za každou radu nebo postrčení správným směrem
-
v perlu třeba takhle:
#!/usr/bin/perl
use 5.012;
use autodie;
use Data::Dumper;
my $log = <<EOF
SCR01 14:41
SCR02 14:42
SCR03 14:43
SCR02 14:44
SCR04 14:45
SCR02 14:46
EOF
;
my $map_table = <<EOF
SCR01 login
SCR02 main page
SCR03 left menu
SCR04 1. content
EOF
;
my %map;
open my ($map_tab), '<', \$map_table;
my %map_tableh = map { chomp; split /\s+/, $_, 2 } <$map_tab>;
close $map_tab;
open my ($logh), '<', \$log;
while (<$logh>) {
chomp;
my ($key) = split /\s+/, $_, 2;
say $_, q{ }, $map_tableh{$key};
}
close $logh;
PS. pro čtení ze souboru stačí změnit \$log a \$map_table za jména souborů
-
Pomocou join (ktory som doteraz vlastne ani nepoznal). Kedze sa to ale najprv predtym sort-uje, tak pri rovnakych casoch moze riadky prehodit ...
f1=$1
f2=$2
f1s=$f1.sort
f2s=$f2.sort
sort $f1 > $f1s
sort $f2 > $f2s
join -a 1 -2 1 $f1s $f2s | sort -k 2
rm -f $f1s $f2s
-
awk. rychlé, spolehlivé. i pro tisícové číselníky :)
http://stackoverflow.com/questions/5467690/how-to-merge-two-files-using-awk
-
Subory pomenujem takto:
file_map.txt
SCR01 login
SCR02 main page
SCR03 left menu
SCR04 1. content
file_log.txt
SCR01 14:41
SCR02 14:42
SCR03 14:43
SCR02 14:44
SCR04 14:45
SCR02 14:46
Takto vyzera awk skript:
join_map_log.awk
# Run:
# awk -f join_map_log.awk file_map.txt file_log.txt
BEGIN {
FS = " "
lines_found = 0
}
{
if (FILENAME == ARGV[1]) {
# mark line from $2 to $NF from file_map.txt in array
line_array[$1] = substr($0, length($1)+1, length($0)-length($1)+1)
}
if (FILENAME == ARGV[2]) {
# print adequate lines from file_log.txt
if (line_array[$1]) {
# concat and print
print $0 line_array[$1]
lines_found ++
}
}
}
END {
printf "\nThere were %d lines found and printed.\n", lines_found
}
Po spusteni dostaneme vysledok:
$ awk -f join_map_log.awk file_map.txt file_log.txt
SCR01 14:41 login
SCR02 14:42 main page
SCR03 14:43 left menu
SCR02 14:44 main page
SCR04 14:45 1. content
SCR02 14:46 main page
There were 6 lines found and printed.
-
Díky moc všem za odpovědi, zkoušel jsem ten skript od mikrom a pal pročítal ten odkaz od alfi. Nakonec jsem použil na těch stránkách popisovaný příkaz s AWK:
$ awk 'FNR==NR{a[$1]=$2 FS $3;next}{ print $0, a[$1]}' file2 file1