[英]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_count
和display_corpus_vocab
。
你試一試:
open (OUT, '>', "document_corpus.txt");
select OUT;
$lsa->get_corpus_vocabulary_and_word_counts();
$lsa->display_corpus_vocab();
select STDOUT;
close (OUT);
這應該工作。 該方法的內部代碼包含print
和printf
,我不知道printf
是否受select
語句的約束。 select
文檔說這會影響write
和print
,沒有提到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_counts
和display_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.