簡體   English   中英

Perl:如何將函數結果打印到文件?

[英]Perl : How to print to a file the result of a function?

我有一個腳本,其中包含以下幾行:

$lsa->get_corpus_vocabulary_and_word_counts();

$lsa->generate_document_vectors();

$lsa->display_corpus_vocab();

$lsa->display_doc_vectors();

但是它顯示在命令行中。 我希望將其顯示在文件中。 所以我嘗試了這個:

open(OUT, '>', "corpus.txt") or die;
print (OUT $lsa->display_corpus_vocab());
close (OUT);

但這不起作用...有幫助嗎? 謝謝!

編輯:

是的,它來自CPAN模塊算法:: VSM。 我在使用此模塊時遇到一些困難。

這里是一個鏈接: https : //metacpan.org/pod/Algorithm :: VSM

我從中提取那些fex代碼行的Perl文件是“ calculate_precision_and_recall_for_LSA”。

感謝您的所有回答! 明天我會嘗試的,如果我設法使它工作,請盡快通知您:)。

編輯2:

這是一個完整的示例文件:

#!/usr/bin/perl -w

### retrieve_with_LSA.pl

#use lib '../blib/lib', '../blib/arch';

use strict;
use Algorithm::VSM;

my $corpus_dir = "corpus";

my @query = qw/dog cat/;

my $stop_words_file = "stop_words.txt";    # This file will typically include the
                                       # keywords of the programming
                                       # language(s) used in the software.

#     The two databases named below store the corpus vocabulary word
#     frequency histogram, and the doc vectors for the files in the corpus, and
#     the doc vectors in a reduced-dimensionality LSA representation of the
#     corpus, respectively.  After these three databases are created, you
#     can do VSM retrieval directly from the databases by running the
#     script retrieve_with_disk_based_LSA.pl.  Doing retrieval using a
#     pre-stored model of a corpus will, in general, be much faster since
#     you will be spared the bother of having to create the model.
my $corpus_vocab_db = "corpus_vocab_db";
my $doc_vectors_db  = "doc_vectors_db";
my $normalized_doc_vecs_db  = "normalized_doc_vecs_db";

my $lsa = Algorithm::VSM->new(
               corpus_directory         => $corpus_dir,
               corpus_vocab_db          => $corpus_vocab_db,
               doc_vectors_db           => $doc_vectors_db,
               normalized_doc_vecs_db   => $normalized_doc_vecs_db,
#                   use_idf_filter           => 0,
               stop_words_file          => $stop_words_file,
               want_stemming            => 1,        # Default is no stemming
               lsa_svd_threshold        => 0.01,# Used for rejecting singular
                                                # values that are smaller than
                                                # this threshold fraction of
                                                # the largest singular value.
               max_number_retrievals    => 10,
#                  debug                    => 1,
      );

$lsa->get_corpus_vocabulary_and_word_counts();

#   Uncomment the following if you would like to see the corpus vocabulary:
$lsa->display_corpus_vocab();

open (OUT, '>', "document_corpus.txt");
select OUT;
print OUT $lsa->get_corpus_vocabulary_and_word_counts();
print OUT $lsa->display_corpus_vocab();
select STDOUT;
close (OUT);

#    Uncomment the following statement if you would like to see the inverse
#    document frequencies:
#$lsa->display_inverse_document_frequencies();

$lsa->generate_document_vectors();

$lsa->display_doc_vectors();

$lsa->display_normalized_doc_vectors();

$lsa->construct_lsa_model();

my $retrievals = $lsa->retrieve_with_lsa( \@query );

$lsa->display_retrievals( $retrievals );

但這仍然行不通...

在調用任何方法之前,需要使用select來使OUT成為“當前選定的文件句柄”:

open(OUT, '>', "corpus.txt") or die;
select OUT; 
$lsa->get_corpus_vocabulary_and_word_counts();
$lsa->generate_document_vectors();    
$lsa->display_corpus_vocab();
$lsa->display_doc_vectors();
select STDOUT;  # This "unselects" OUT.
close OUT;

我相信您正在使用Algorithm :: VSM 真的嗎?

我正在查看源代碼 ,可以看到各種方法中都嵌入了print語句。 例如, $lsa->display_corpus_vocab打印出“ Displaying corpus vocabulary: ”行,列出單詞,然后打印Displaying corpus vocabulary: Size of the corpus vocabulary: $vocab_size

幸運的是,打印語句可以打印到默認文件句柄。 這意味着,我們可以使用select作為jwodder表明在他們的答案。

(如果該模塊的作者希望真正成為邪惡的人,他們可以完成print STDOUT "...";這意味着即使select也不起作用。)

它還向我們展示了為什么您從未將print語句放入模塊中。 如果某個模塊假設要報告信息 ,則它應該返回此信息,而不是直接打印出來,因此用戶可以根據自己的意願處置這些信息。

但是,您需要謹慎使用select 如果您想打印一些文件以外的內容怎么辦? 我建議您在每次調用之前和之后使用select ,如下所示:

 my $orig_fh = select;    # Original "default" Filehandle (probably STDOUT)
...
select ( OUT );   # Output of display_corpus_vocab to my file
$lhs->display_corpus_vocab;
select ( $orig_fh );     # Reset program back to STDOUT (or original default FH).

附錄

我編輯了我的第一篇文章。 我使用了select,但是它仍然不起作用。 你知道怎么了嗎 再次感謝。 –用戶3443814

剛開始,我非常關心select語句。 當我最初寫這篇文章時,我有一個有點古怪的感覺, select可能對名稱空間敏感,並且由於這些方法在另一個包中 ,因此select語句不太起作用。 我沒有看到任何相關的文檔,所以我確信情況並非如此。

當您發表評論說它行不通時,我想哦,不 ,但是,在查看了您的操作后,我現在發現問題可能出在您的代碼上。 你有這個:

open (OUT, '>', "document_corpus.txt");
select OUT;
print OUT $lsa->get_corpus_vocabulary_and_word_counts();
print OUT $lsa->display_corpus_vocab();
select STDOUT;
close (OUT);

您根本不應該使用print OUT ,因為print語句本身在方法get_corpus_vocabulary_and_word_countdisplay_corpus_vocab

你試一試:

open (OUT, '>', "document_corpus.txt");
select OUT;
$lsa->get_corpus_vocabulary_and_word_counts();
$lsa->display_corpus_vocab();
select STDOUT;
close (OUT);

應該工作。 該方法的內部代碼包含printprintf ,我不知道printf是否受select語句的約束。 select文檔說這會影響writeprint ,沒有提到printf 但是, printf文檔說這等效於print sprintf... 因此,我認為printf應該服從select的要求。

如果您編寫的文件完全不包含任何內容,那么我們知道select有效。 如果它不包含您的所有信息,並且仍然在終端上打印了一些信息,則很有可能printf不受select影響。 我還沒有測試這種可能性。

如果您的輸出文件完全為空,則可能是select名稱空間敏感。

您可以嘗試更改進行選擇的名稱空間,看看是否可以解決問題:

package Algorithm:VSM;
open (OUT, '>', "document_corpus.txt");
select OUT;
package main;
$lsa->get_corpus_vocabulary_and_word_counts();
$lsa->display_corpus_vocab();
package Algorithm:VSM
select STDOUT;
close (OUT);
package main;

package語句更改名稱空間。 默認情況下,Perl使用默認的main名稱空間。 當您打開文件並進行選擇時,我正在做的是更改為Algorithm::VSM命名空間。 這是Algorithm::VSM包使用的名稱空間。 希望如果select受其所在的名稱空間影響,則可以解決此問題。

否則,您需要在幕后偷看,這樣可以說一下並看一下Algorithm::VSM模塊中的代碼。 您可以通過執行以下命令找到它的位置:

$ perldoc -l Algorithm::VSM

查看子例程get_corpus_vocabulary_and_word_countsdisplay_corpus_vocab的代碼,看看這些打印語句是否是沒有文件句柄的簡單普通舊打印語句,或者該模塊是否將輸出強制為STDOUT。

如果您可以編輯模塊的代碼(您需要成為系統管理員才能執行此操作),則可以嘗試添加:

warn "SELECT FH " . select;

在代碼中的方法中查看其輸出內容。

我希望其他人可以看到這篇文章,指出我完全的無知,並解釋真正發生的事情以及為什么我完全錯了。

如果您不想使用select,一些替代方法:

1.使用正確的語法打印到文件句柄

print {OUT} $lsa->display_corpus_vocab();
close(OUT);

2.將腳本的標准輸出重定向到文件

perl myscript.pl > corpus.txt  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM