LINUX.ORG.RU
ФорумAdmin

awk замена значения поля значением из файла


0

0

Есть файл с записями вида

192.168.1.3,2346546

и второй с записями вида

192.168.1.3 Username

нужно получить из них файл с записями

Username,2346546

system() насколько я понял возвращает код завершения, соответственно через него дёргать grep смысла не имеет. Вроде бы можно выбирать нужную строку из второго файла через getline, но уж очень не хочется вручную искать.

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

Но на нашем чудном лоре есть еще много интересных людей, владеющих забытыми наречиями. Поэтому ждем кучу хитровы@нных однострочников на седе и авк :)

P.S. Слеш ми ушел за попокорном.

nnz ★★★★
()

Впрочем, есть способ даже еще проще - мускул :)

Создать таблицы для обоих файлов, прочитать в них файлы через load data infile, примерно так
load data local infile 'файл1' into table file1 fields terminated by ','
затем сделать селект сразу в файл
select file2.username, file1.num from file1, file2 where file1.ip=file2.ip into outfile 'имя файла' fields terminated by ','

за синтаксические ошибки фирма ответственности не несет ;)

nnz ★★★★
()

#!/usr/bin/env python
# -*- coding: utf8 -*-

def write_log(tmp_str, tmp_path):
    try:
        file = open(tmp_path,'a')
        file.write(tmp_str + '\n')
        file.close()
        return 1
    except IOError, err:
        return 0

#================================================================
def read_log(tmp_path):
    try:
        file = open(tmp_path)
        text = file.readlines()
        file.close()
        return text
    except IOError, err:
        return 0

#================================================================
if __name__ == "__main__":

    path1 = './1.txt'
    path2 = './2.txt'
    path3 = './3.txt'

    a = read_log(path1)
    b = read_log(path2)

    for line_a in a:
        digit = line_a.split(',')[1].split('\n')[0]
        ip_a = line_a.split(',')[0]
        for line_b in b:
            ip_b = line_b.split(' ')[0]
            user = line_b.split(' ')[1].split('\n')[0]
            if(ip_a == ip_b):
                #print user + ',' + digit
                write_log(user + ',' + digit, path3)

joinordie
()
Ответ на: комментарий от joinordie

Так не интересно :(

ТруЪ программеры обычно меряются, у кого код короче. А у кого длиннее - это уже к коду не относится :)

nnz ★★★★
()

>Вроде бы можно выбирать нужную строку из второго файла через getline, но уж очень не хочется вручную искать.

Если размеры файлов позволяют их засунуть в ОЗУ, то создавайте массив из одно файла, а потом читате другой файл и выводите.

>system() насколько я понял возвращает код завершения...

Да, код завершения, для получения stdout команды есть конструкция вида "command | getline", но вызывать grep из awk это как то брутально.

mky ★★★★★
()
Ответ на: комментарий от mky

BEGIN {
        rname_path = "/var/www/lightsquid-1.7.1/realname.cfg"
        FS = "\t"
        while ((getline rname_str < rname_path) > 0) {
                sep = index(rname_str, "\t")
                key = substr(rname_str, 0, sep)
                val = substr(rname_str, sep + 1)
                rnames[key] = val
        }
        FS = ","
}
{
        if ($1 != "#") {
                sum = sum + $2
                if (rnames[$1]) {
                        print rnames[$1] "," $2/1024/1024 "M"
                }
                else
                        print $1 "," $2/1024/1024 "M"
        }
        else {
                print $0
        }
}
END {
        print "Total: " sum/1024/1024 "M"
}

Анальные кровотечения означают, что это работает. Как более кошерно проверить наличие в массиве элемента с заданным ключом?

Lonli-Lokli ★★
() автор топика
Ответ на: комментарий от Lonli-Lokli

Как в man'е написано:
if (key in array)
                   print array[key]

Проход по всем элементам массива через while:
if (key in array)
                   print array[key]

mky ★★★★★
()

Питоны, массивы, хеши.... Жуть.

#!/bin/bash
#

FILE1=$1
FILE2=$2
NEWFILE=$3

NUM=`cat ${FILE1} | wc -l`

for ((i=1;i<=${NUM};i++)) 
do
  WORD1=`head -n $i ${FILE1} | tail -n 1 | awk -F , '{printf $2}'`
  WORD2=`head -n $i ${FILE2} | tail -n 1 | awk '{printf $2}'`
  echo "${WORD2},${WORD1}" >> $NEWFILE
done

shell-script ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.