Mam dwa pliki i muszę usunąć linie, które spada pod pewnym współczynnikiem token, np.

Plik 1:

This is a foo bar question
that is not a parallel sentence because it's too long
hello world

Plik 2:

c'est le foo bar question
creme bulee
bonjour tout le monde

A stosunek obliczony jest całkowity no. of words in file 1 / total no. of words in file 2, a zdania są usuwane, jeśli spadnie w tym stosunku.

Następnie wyjście jest złączem plikiem z zdaniami z pliku1 i pliku2 oddzielone kartą:

[na zewnątrz]:

This is a foo bar question\tc'est le foo bar question
hello world\tbonjour tout le monde

Pliki mają zawsze taką samą liczbę linii. Robiłem to jako przestrzegane, ale , jak zrobić to samo w bash Uniks, zamiast używać Pythona?

# Calculate the ratio.
with io.open('file1', , 'r', encoding='utf8') as f1, io.open('file2', , 'r', encoding='utf8') as f2: 
    ratio = len(f1.read().split()) / float(len(f2.read().split()))
# Check and output to file.
with io.open('file1', , 'r', encoding='utf8') as f1, io.open('file2', , 'r', encoding='utf8') as f2, io.open('fileout', , 'w', encoding='utf8') as fout:
    for l1, l2 in zip(file1, file2):
        if len(l1.split())/float(len(l2.split())) > ratio:
            print>>fout, "\t".join([l1.strip() / l2.strip()])

Ponadto, jeśli obliczenie stosunku opiera się na znakach zamiast słów , mogę to zrobić w Pythonie, ale , jak osiągnąć to samo w UNIX Bash ? Zauważ, że różnica liczy się tylko z len(str.split()) i len(str).

# Calculate the ratio.
with io.open('file1', , 'r', encoding='utf8') as f1, io.open('file2', , 'r', encoding='utf8') as f2: 
    ratio = len(f1.read()) / float(len(f2.read()))
# Check and output to file.
with io.open('file1', , 'r', encoding='utf8') as f1, io.open('file2', , 'r', encoding='utf8') as f2, io.open('fileout', , 'w', encoding='utf8') as fout:
    for l1, l2 in zip(file1, file2):
        if len(l1)/float(len(l2)) > ratio:
            print>>fout, "\t".join([l1.strip() / l2.strip()])
0
alvas 18 sierpień 2014, 08:47

2 odpowiedzi

Najlepsza odpowiedź

Oto prosty kalkulator stosunku w awk.

awk 'NR == FNR { a[NR] = NF; next }
    { print NF/a[FNR] }' file1 file2

To jedynie drukuje stosunek dla każdej linii. Rozszerzenie go do drukowania drugiego pliku, gdy stosunek jest w określonym zakresie jest łatwy.

awk 'NR == FNR { a[NR] = NF; next }
    NF/a[FNR] >= 0.5 && NF/a[FNR] <= 2' file1 file2

(Wykorzystuje skrót w awwarku - w formularzu ogólnym condition { action } Jeśli pomijasz { action } domyślnie do { print }. Podobnie, jeśli pominisz stan, akcja zostanie podjęta bezwarunkowo.)

Możesz uruchomić sekundę nad file1, aby zrobić to samo, lub po prostu uruchom go ponownie za pomocą odwróconych nazw plików.

Och, poczekaj, oto pełne rozwiązanie.

awk 'NR == FNR { a[NR] = NF; w[NR] = $0; next }
    NF/a[FNR] >= 0.5 && NF/a[FNR] <= 2 { print w[FNR] "\t" $0 }' file1 file2
1
tripleee 20 sierpień 2014, 05:51

Komentarz Tripleee, który Bash nie jest dobry dla liczby całkowitych, jest poprawny, ale jeśli naprawdę chcesz robić, to powinno się rozpocząć. Możesz to zrobić z programem wc i argument -w. Liczy się słowa. BC działa między innymi podział.

while read line1 <&3 && read line2 <&4; do     
    line1_count=`echo $line1 | wc -w`
    line2_count=`echo $line2 | wc -w`
    ratio=`echo "$line1_count / $line2_count" | bc -l`
    echo $ratio
done 3<file1 4<file2

Również man bc i spojrzeć na część o wyrażeniach relacyjnych. Które powinno pozwolić Ci wykonać porównanie z każdym progiem na stosunek.

1
user3391564 18 sierpień 2014, 07:44