2013-07-24 3 views
1

Вдумчивый и умный человек немного помог мне с помощью сценария bash, но недавно я понял, что не объяснил, что я хочу достаточно ясно. У меня есть длинный список фраз (ngrams) в текстовом файле. Если одна фраза является фрагментом другой, только более длинная из них используется, поэтому более короткая она должна быть удалена. Код ниже удаляет более длинный. Надеюсь, что переход будет состоять в изменении нескольких персонажей.ngrams (tweak to existing bash script)

#! /bin/bash 
((n=${1:-0})) || exit 1 

declare -A ngrams 

while read -ra line; do 
    for ((i = 0; i < ${#line[@]}; i++)); do 
      ((ngrams[${line[@]:i:n}]++)) 
    done 
done 

for i in "${!ngrams[@]}"; do 
    printf '%d\t%s\n' "${ngrams[$i]}" "$i" 
done 
+1

В конце концов, возможно, он не был таким «задумчивым» (учитывая, что он не объяснил это четко, чтобы позволить вам * ** понимать **). – devnull

+1

@ user1889034 - Можете ли вы привести пример входных данных? Может ли какой-либо из нежелательных фрагментов появляться посреди более желаемых более длинных фрагментов? –

ответ

1

Не изменив несколько символов, но недавно написал:

#! /bin/bash 

declare -a ngrams 
mapfile -t ngrams < $1 
for ((i=0; i<${#ngrams[@]}; i++)); do 
    for ((j=0; j<${#ngrams[@]}; j++)); do 
     if (( i!=j)) && [[ "${ngrams[j]}" == *"${ngrams[i]}"* ]]; then 
      continue 2 
     fi 
    done 
    echo ${ngrams[i]} >> $2 
done 

Вы можете назвать это ngram.sh <infile> <outfile>. Например,

> cat txt.in 
foo 
me me me 
kaaz 
bar 
foo bar 
blub 
me 
> ./ngram.sh txt.in txt.out 
> cat txt.out 
me me me 
kaaz 
foo bar 
blub 
+0

Работает красиво. Спасибо! – user1889034