Bash или Python или Awk для сопоставления и изменения файлов - PullRequest
1 голос
/ 26 января 2010

У меня есть набор из 10000 файлов c1.dat ... c10000.dat. Каждый из этих файлов содержит строку, которая начинается с @ и содержит строку с пробелами, характерными для этого файла, lije c37 7.379 6.23.

У меня есть еще один набор из 10000 файлов, как определено_cXXX_send.dat (где XXX идет от 1 до 10000). Каждый из этих файлов имеет только одну строку. Каждая строка имеет тип:

_1 1 3456,000000 -21 0 -98,112830 -20,326192

Я хотел бы, чтобы для каждого числа XXX (от 1 до 10000) получить из файла cXXX.dat строку, подобную c37 7.379 6.23, и добавить ее в файлtermin_cXXX_send.dat в начало файл, так что я получаю:

с37 7,379 6,23 _1 1 3456,000000 -21 0 -98,112830 -20,326192

Я пробовал и с bash, и с python, но не нашел хорошего решения.

Какой будет лучший подход?

спасибо

Ответы [ 5 ]

1 голос
/ 26 января 2010

Если каждый из двух типов файлов имеет только одну строку:

for i in {1..10000}
do
    paste "c${i}.dat" "determined_c${i}_send.dat" > c${i}.out && 
    mv "c{$i}.out" "determined_c${i}_send.dat"
done

Edit:

for i in {1..10000}
do
    line=$(grep -o "^c${i}.*")
    line="${line#@*}"
    read data < determined_c${i}_send.dat
    echo "$line $data" > c${i}.out &&
    mv "c{$i}.out" "determined_c${i}_send.dat"
done
1 голос
/ 26 января 2010

В Python вы можете сделать что-то подобное

# loop on all the files
for num in range(1,1000):

    cfile = open ( 'c%u.dat'%num, mode='r')

    # find the specific line
    for line in cfile:
        if line[0]=='@':

            # open the determined file and add the line
            dfile = open( 'determined_c%u_send.dat'%num, mode='a')
            dfile.write( line[1:-1] )
            dfile.close()

    cfile.close()

Не проверено, но должно работать

РЕДАКТИРОВАТЬ: я понял, что вы хотите добавить строку в начале определенный_cXXX_send.dat, а не в конце.

Итак, основываясь на ответе Денниса Уильямсона, я также могу предложить следующий код bash

for i in {1..2}
do
    mv "determined_c${i}_send.dat" "temp.out"
    cat c1.dat | grep @ | tr -d "@" >  "determined_c${i}_send.dat"
    cat temp.out >> "determined_c${i}_send.dat"
done
rm temp.out
1 голос
/ 26 января 2010

Язык, в основном созданный для обработки текста: Perl!

0 голосов
/ 26 января 2010

если «c37 7.379 6.23» является константой, то нет необходимости извлекать эту строку из файлов cXXX.dat. Но я предполагаю, что эта строка является динамической, и она идет после @., Так что вы можете попробовать это

#!/bin/bash
shopt -s nullglob
for file in c{1..1000}.dat
do
    if [ -e "$file" ];then
        tag=${file%.dat}
        while read -r line
        do
            case "$line" in
                @*)
                    mystring=${line##@};;
            esac
        done < "$file"
        if [ -e "determined_${tag}_send.dat" ]; then
            while read -r line
            do
                echo "$mystring $line"
            done < "determined_${tag}_send.dat" > temp
            mv temp "determined_${tag}_send.dat"
        fi
    fi
done

выход

$ cat c1.dat
@ c37 7.379 6.23

$ cat determined_c1_send.dat
_1 1 3456.000000 -21 0 -98.112830 -20.326192

$ ./shell.sh
$ cat determined_c1_send.dat
 c37 7.379 6.23 _1 1 3456.000000 -21 0 -98.112830 -20.326192
0 голосов
/ 26 января 2010

Выполнение этого в Python должно быть довольно тривиальным. Это возможно в awk, но звучит слишком сложно, чтобы быть веселым. Конечно, это возможно в bash, но программирование в bash предназначено для мазохистов.

Я бы пошел с Python, из указанных опций, хотя Perl и Ruby также хороши, если вы их знаете.

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