如何在同一行打印?

huangapple go评论112阅读模式
英文:

How to print the in same line?

问题

  1. #use Data::Dumper;
  2. my $file3 = 'file1.csv';
  3. my $file2 = 'file2.csv';
  4. my $file1 = 'file3.csv';
  5. open (my $fh_dest, ">", "outputfile.csv") or die "无法打开 outputfile.csv: $!";
  6. my %HoA1;
  7. my %HoA2;
  8. my %HoA3;
  9. open (MODIFIED_FILE2, $file1) or die ("无法打开 $file1!");
  10. while(<MODIFIED_FILE2>){
  11. chomp;
  12. my ($k, $v1,$v2,$v3,$v4) = split /,/,$_,5;
  13. push @{$HoA1{'MODIFIED_FILE2'}{$k}},$v1,$v2,$v3,$v4;
  14. }
  15. close(MODIFIED_FILE2);
  16. open (MODIFIED_FILE1, $file2) or die ("无法打开 $file2!");
  17. while(<MODIFIED_FILE1>){
  18. chomp;
  19. my ($k, $v1,$v2,$v3) = split /,/,$_,4;
  20. push @{$HoA2{'MODIFIED_FILE1'}{$k}},$v1,$v2,$v3;
  21. }
  22. close(MODIFIED_FILE1);
  23. open (BASE_FILE, $file3) or die ("无法打开 $file3!");
  24. while(<BASE_FILE>){
  25. chomp;
  26. my ($k, $v1,$v2,$v3) = split /,/,$_,4;
  27. push @{$HoA3{'BASE_FILE'}{$k}},$v1,$v2,$v3;
  28. }
  29. close(BASE_FILE);
  30. #print $fh_dest Dumper \%HoA;
  31. foreach my $MODIFIED_FILE2 (keys %{ $HoA1{'MODIFIED_FILE2'} }) {
  32. if (exists $HoA3{'BASE_FILE'}{$MODIFIED_FILE2}) {
  33. print $fh_dest "-" x 60, "\n";
  34. print $fh_dest "$MODIFIED_FILE2\nMODIFIED_FILE2\t MODIFIED_FILE1 BASE_FILE\n";
  35. print $fh_dest "-" x 60, "\n";
  36. foreach my $class_BASE_FILE ( @{$HoA3{'BASE_FILE'}{$MODIFIED_FILE2}} ) {
  37. printf $fh_dest "%-20s%-20s%s\n",$class_MODIFIED_FILE2,$class_MODIFIED_FILE1,$class_BASE_FILE;
  38. }
  39. foreach my $class_MODIFIED_FILE1 ( @{$HoA2{'MODIFIED_FILE1'}{$MODIFIED_FILE2}} ) {
  40. printf $fh_dest "%-20s%s\n",$class_MODIFIED_FILE2,$class_MODIFIED_FILE1;
  41. }
  42. foreach my $class_MODIFIED_FILE2 ( @{$HoA1{'MODIFIED_FILE2'}{$MODIFIED_FILE2}} ) {
  43. printf $fh_dest "%s\n",$class_MODIFIED_FILE2;
  44. }
  45. print $fh_dest "\n";
  46. }
  47. elsif (exists $HoA2{'MODIFIED_FILE1'}{$MODIFIED_FILE2}) {
  48. print $fh_dest "-" x 60, "\n";
  49. print $fh_dest "$MODIFIED_FILE2\nMODIFIED_FILE2\t MODIFIED_FILE1 BASE_FILE\n";
  50. print $fh_dest "-" x 60, "\n";
  51. foreach my $class_MODIFIED_FILE1 ( @{$HoA2{'MODIFIED_FILE1'}{$MODIFIED_FILE2}} ) {
  52. printf $fh_dest "%-20s%s\n",$class_MODIFIED_FILE2,$class_MODIFIED_FILE1;
  53. }
  54. foreach my $class_MODIFIED_FILE2 ( @{$HoA1{'MODIFIED_FILE2'}{$MODIFIED_FILE2}} ) {
  55. printf $fh_dest "%s\n",$class_MODIFIED_FILE2;
  56. }
  57. print $fh_dest "\n";
  58. }
  59. else {
  60. print $fh_dest "-" x 60, "\n";
  61. print $fh_dest "$MODIFIED_FILE2\nMODIFIED_FILE2\t MODIFIED_FILE1 BASE_FILE\n";
  62. print $fh_dest "-" x 60, "\n";
  63. foreach my $class_MODIFIED_FILE2 ( @{$HoA1{'MODIFIED_FILE2'}{$MODIFIED_FILE2}} ) {
  64. printf $fh_dest "%s\n",$class_MODIFIED_FILE2;
  65. }
  66. print $fh_dest "\n";
  67. }
  68. }
  69. close ($fh_dest);
英文:

I having problem in printing the hash element in same line.

  1. t#!/usr/bin/perl
  2. #use Data::Dumper;
  3. my $file3 = &#39;file1.csv&#39;;
  4. my $file2 = &#39;file2.csv&#39;;
  5. my $file1 = &#39;file3.csv&#39;;
  6. open (my $fh_dest, &quot;&gt;&quot;, &quot;outputfile.csv&quot;) or die &quot;Can&#39;t open &gt; outputfile.csv: $!&quot;;
  7. my %HoA1;
  8. my %HoA2;
  9. my %HoA3;
  10. open (MODIFIED_FILE2, $file1) or die (&quot;Could not open $file1!&quot;);
  11. while(&lt;MODIFIED_FILE2&gt;){
  12. chomp;
  13. my ($k, $v1,$v2,$v3,$v4) = split /,/,$_,5;
  14. push @{$HoA1{&#39;MODIFIED_FILE2&#39;}{$k}},$v1,$v2,$v3,$v4;
  15. }
  16. close(MODIFIED_FILE2);
  17. open (MODIFIED_FILE1, $file2) or die (&quot;Could not open $file2!&quot;);
  18. while(&lt;MODIFIED_FILE1&gt;){
  19. chomp;
  20. my ($k, $v1,$v2,$v3) = split /,/,$_,4;
  21. push @{$HoA2{&#39;MODIFIED_FILE1&#39;}{$k}},$v1,$v2,$v3;
  22. }
  23. close(MODIFIED_FILE1);
  24. open (BASE_FILE, $file3) or die (&quot;Could not open $file3!&quot;);
  25. while(&lt;BASE_FILE&gt;){
  26. chomp;
  27. my ($k, $v1,$v2,$v3) = split /,/,$_,4;
  28. push @{$HoA3{&#39;BASE_FILE&#39;}{$k}},$v1,$v2,$v3;
  29. }
  30. close(BASE_FILE);
  31. #print $fh_dest Dumper \%HoA;
  32. foreach my $MODIFIED_FILE2 (keys %{ $HoA1{&#39;MODIFIED_FILE2&#39;} }) {
  33. if (exists $HoA3{&#39;BASE_FILE&#39;}{$MODIFIED_FILE2}) {
  34. print $fh_dest &quot;-&quot; x 60, &quot;\n&quot;;
  35. print $fh_dest &quot;$MODIFIED_FILE2\nMODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE\n&quot;;
  36. print $fh_dest &quot;-&quot; x 60, &quot;\n&quot;;
  37. foreach my $class_BASE_FILE ( @{$HoA3{&#39;BASE_FILE&#39;}{$MODIFIED_FILE2}} ) {
  38. printf $fh_dest &quot;%-20s%-20s%s\n&quot;,$class_MODIFIED_FILE2,$class_MODIFIED_FILE1,$class_BASE_FILE;
  39. }
  40. foreach my $class_MODIFIED_FILE1 ( @{$HoA2{&#39;MODIFIED_FILE1&#39;}{$MODIFIED_FILE2}} ) {
  41. printf $fh_dest &quot;%-20s%s\n&quot;,$class_MODIFIED_FILE2,$class_MODIFIED_FILE1;
  42. }
  43. foreach my $class_MODIFIED_FILE2 ( @{$HoA1{&#39;MODIFIED_FILE2&#39;}{$MODIFIED_FILE2}} ) {
  44. printf $fh_dest &quot;%s\n&quot;,$class_MODIFIED_FILE2;
  45. }
  46. print $fh_dest &quot;\n&quot;;
  47. }
  48. elsif (exists $HoA2{&#39;MODIFIED_FILE1&#39;}{$MODIFIED_FILE2}) {
  49. print $fh_dest &quot;-&quot; x 60, &quot;\n&quot;;
  50. print $fh_dest &quot;$MODIFIED_FILE2\nMODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE\n&quot;;
  51. print $fh_dest &quot;-&quot; x 60, &quot;\n&quot;;
  52. foreach my $class_MODIFIED_FILE1 ( @{$HoA2{&#39;MODIFIED_FILE1&#39;}{$MODIFIED_FILE2}} ) {
  53. printf $fh_dest &quot;%-20s%s\n&quot;,$class_MODIFIED_FILE2,$class_MODIFIED_FILE1;
  54. }
  55. foreach my $class_MODIFIED_FILE2 ( @{$HoA1{&#39;MODIFIED_FILE2&#39;}{$MODIFIED_FILE2}} ) {
  56. printf $fh_dest &quot;%s\n&quot;,$class_MODIFIED_FILE2;
  57. }
  58. print $fh_dest &quot;\n&quot;;
  59. }
  60. else {
  61. print $fh_dest &quot;-&quot; x 60, &quot;\n&quot;;
  62. print $fh_dest &quot;$MODIFIED_FILE2\nMODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE\n&quot;;
  63. print $fh_dest &quot;-&quot; x 60, &quot;\n&quot;;
  64. foreach my $class_MODIFIED_FILE2 ( @{$HoA1{&#39;MODIFIED_FILE2&#39;}{$MODIFIED_FILE2}} ) {
  65. printf $fh_dest &quot;%s\n&quot;,$class_MODIFIED_FILE2;
  66. }
  67. print $fh_dest &quot;\n&quot;;
  68. }
  69. }
  70. close ($fh_dest);

The output I get :

  1. ------------------------------------------------------------
  2. Dora
  3. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  4. ------------------------------------------------------------
  5. 34
  6. Malaysian
  7. Malay
  8. 34
  9. Malaysian
  10. Arab
  11. B-
  12. ------------------------------------------------------------
  13. Boszor
  14. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  15. ------------------------------------------------------------
  16. 91
  17. Mexico
  18. Chinese
  19. 91
  20. Mexico
  21. Chinese
  22. 91
  23. Mexico
  24. Chinese
  25. AB+
  26. ------------------------------------------------------------
  27. Szundi
  28. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  29. ------------------------------------------------------------
  30. 23
  31. German
  32. Indian
  33. 23
  34. German
  35. Indian
  36. 23
  37. German
  38. Indian
  39. AB-

the expected output:

  1. -----------------------------------------------------------
  2. Dora
  3. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  4. ------------------------------------------------------------
  5. 34 34
  6. Malaysian Malaysian
  7. Malay Arab
  8. B-
  9. ------------------------------------------------------------
  10. Boszor
  11. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  12. ------------------------------------------------------------
  13. 91 91 91
  14. Mexico Mexico Mexico
  15. Chinese Chinese Chinese
  16. AB+
  17. ------------------------------------------------------------
  18. Szundi
  19. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  20. ------------------------------------------------------------
  21. 23 23 23
  22. German German German
  23. Indian Indian Indian
  24. AB-

答案1

得分: 2

这是您提供的Perl代码的翻译部分:

  1. 有一个Perl的相对古老的特性完全符合您的要求 --- "format"
  2. #!/usr/bin/env perl
  3. use strict;
  4. use warnings;
  5. use Data::Dumper;
  6. my $name = '';
  7. my $v = undef;
  8. format STDOUT =
  9. -----------------------------------------------------------
  10. @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  11. $name
  12. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  13. -----------------------------------------------------------
  14. #==================#===================#===================#
  15. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  16. $v->[0][0]//'', $v->[1][0]//'', $v->[2][0]//'',
  17. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  18. $v->[0][1]//'', $v->[1][1]//'', $v->[2][1]//'',
  19. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  20. $v->[0][2]//'', $v->[1][2]//'', $v->[2][3]//'',
  21. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  22. $v->[0][3]//'', $v->[1][3]//'', $v->[2][3]//''
  23. .
  24. {
  25. # 测试格式
  26. # 在循环开始时清除列
  27. $v = undef;
  28. # 为各行设置值
  29. $name = 'decline the in german';
  30. # 在第三列中设置要使用的值
  31. $v->[2] = [qw(das des dem das)];
  32. # 在第二列中设置要使用的值
  33. $v->[1] = [qw(die der der die)];
  34. # 在第一列中设置要使用的值
  35. $v->[0] = [qw(der des dem den)];
  36. {
  37. # 安全地输出格式化的STDOUT
  38. my $old_handle = select STDOUT;
  39. # 这将进入$new_handle:
  40. write;
  41. # 恢复以前的句柄
  42. select $old_handle;
  43. };
  44. };
  45. 对于我们的测试这会产生以下结果
  46. -----------------------------------------------------------
  47. decline the in germ
  48. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  49. -----------------------------------------------------------
  50. der die das
  51. des der des
  52. dem der das
  53. den die das
  54. 使用这个我们可以简化您的代码为
  55. #!/usr/bin/env perl
  56. use strict;
  57. use warnings;
  58. use Data::Dumper;
  59. my $name = '';
  60. my $v = undef;
  61. format STDOUT =
  62. -----------------------------------------------------------
  63. @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  64. $name
  65. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  66. -----------------------------------------------------------
  67. #==================#===================#===================#
  68. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  69. $v->[0][0]//'', $v->[1][0]//'', $v->[2][0]//'',
  70. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  71. $v->[0][1]//'', $v->[1][1]//'', $v->[2][1]//'',
  72. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  73. $v->[0][2]//'', $v->[1][2]//'', $v->[2][3]//'',
  74. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  75. $v->[0][3]//'', $v->[1][3]//'', $v->[2][3]//''
  76. .
  77. if (0) { # 这只是用来检查我们的格式
  78. # 测试格式
  79. # 在循环开始时清除列
  80. $v = undef;
  81. # 为各行设置值
  82. $name = 'decline the in german';
  83. # 在第三列中设置要使用的值
  84. $v->[2] = [qw(das des dem das)];
  85. # 在第二列中设置要使用的值
  86. $v->[1] = [qw(die der der die)];
  87. # 在第一列中设置要使用的值
  88. $v->[0] = [qw(der des dem den)];
  89. {
  90. # 安全地输出格式化的STDOUT
  91. my $old_handle = select STDOUT;
  92. # 这将进入$new_handle:
  93. write;
  94. # 恢复以前的句柄
  95. select $old_handle;
  96. };
  97. };
  98. my %HoHoA;
  99. sub read_csv {
  100. my ($filename, $tag, $values) = @_;
  101. open(my $FILE, '<', $filename)
  102. or die "Could not open '$filename'! $!";
  103. my %HoA;
  104. while (<$FILE>) {
  105. chomp;
  106. my ($k, @value) = split /,/, $_, $values;
  107. $HoHoA{$k}{$tag} = \@value;
  108. }
  109. close($FILE);
  110. } # 子程序read_csv
  111. # 读取数据
  112. read_csv('file3.csv', 'MODIFIED_FILE2', 5);
  113. read_csv('file2.csv', 'MODIFIED_FILE1', 4);
  114. read_csv('file1.csv', 'BASE_FILE', 4);
  115. #;warn Data::Dumper->new([\%HoHoA],[qw(*HoHoA)])->Deepcopy(1)->Indent(1)->Maxdepth(3)->Sortkeys(1)->Dump(),q{ };
  116. for my $key (sort keys %HoHoA) {
  117. # 清除/设置在格式中使用的值
  118. $name = $key;
  119. $v = undef;
  120. # 将数据放入列中 --- 仅供娱乐,它们的顺序是错乱的
  121. $v->[2] = $HoHoA{$key}{'BASE_FILE'} # 第三列
  122. if (exists $HoHoA{$key}{'BASE_FILE'});
  123. $v->[1] = $HoHoA{$key}{'MODIFIED_FILE1'} # 第二列
  124. if (exists $HoHoA{$key}{'MODIFIED_FILE1'});
  125. $v->[0] = $HoHoA{$key}{'MODIFIED_FILE2'}; # 第一列
  126. {
  127. # 安全地输出格式化的STDOUT
  128. my $old_handle = select STDOUT;
  129. # 这将进入$new_handle:
  130. write;
  131. # 恢复以前的句柄
  132. select $old_handle;
  133. };
  134. }
  135. __DATA__

这是您提供的Perl代码的部分翻译。如果您需要更多的帮助或有其他问题,请随时提问。

英文:

There is a somewhat archiac feature of perl that does exactly what you were looking for --- the "format".

  1. #!/usr/bin/env perl
  2. use strict;
  3. use warnings;
  4. use Data::Dumper;
  5. my $name=&#39;&#39;;
  6. my $v=undef;
  7. format STDOUT =
  8. -----------------------------------------------------------
  9. @&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
  10. $name
  11. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  12. ------------------------------------------------------------
  13. #==================#===================#===================#
  14. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  15. $v-&gt;[0][0]//&#39;&#39;, $v-&gt;[1][0]//&#39;&#39;, $v-&gt;[2][0]//&#39;&#39;,
  16. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  17. $v-&gt;[0][1]//&#39;&#39;, $v-&gt;[1][1]//&#39;&#39;, $v-&gt;[2][1]//&#39;&#39;,
  18. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  19. $v-&gt;[0][2]//&#39;&#39;, $v-&gt;[1][2]//&#39;&#39;, $v-&gt;[2][3]//&#39;&#39;,
  20. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  21. $v-&gt;[0][3]//&#39;&#39;, $v-&gt;[1][3]//&#39;&#39;, $v-&gt;[2][3]//&#39;&#39;
  22. .
  23. {
  24. # Test format
  25. # clear the columns at the beginning of the loop
  26. $v=undef;
  27. # set values for the various lines
  28. $name=&#39;decline the in german&#39;;
  29. # set values to used in third column
  30. $v-&gt;[2]=[qw(das des dem das)];
  31. # set values to used in second column
  32. $v-&gt;[1]=[qw(die der der die)];
  33. # set values to used in first column
  34. $v-&gt;[0]=[qw(der des dem den)];
  35. {
  36. # Safely output the format STDOUT
  37. my $old_handle=select STDOUT;
  38. # This goes to $new_handle:
  39. write;
  40. # restore the perevious handle
  41. select $old_handle;
  42. };
  43. };

For our test this yields

  1. -----------------------------------------------------------
  2. decline the in germ
  3. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  4. ------------------------------------------------------------
  5. der die das
  6. des der des
  7. dem der das
  8. den die das

Using this we can simplify your code to

  1. #!/usr/bin/env perl
  2. use strict;
  3. use warnings;
  4. use Data::Dumper;
  5. my $name=&#39;&#39;;
  6. my $v=undef;
  7. format STDOUT =
  8. -----------------------------------------------------------
  9. @&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
  10. $name
  11. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  12. ------------------------------------------------------------
  13. #==================#===================#===================#
  14. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  15. $v-&gt;[0][0]//&#39;&#39;, $v-&gt;[1][0]//&#39;&#39;, $v-&gt;[2][0]//&#39;&#39;,
  16. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  17. $v-&gt;[0][1]//&#39;&#39;, $v-&gt;[1][1]//&#39;&#39;, $v-&gt;[2][1]//&#39;&#39;,
  18. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  19. $v-&gt;[0][2]//&#39;&#39;, $v-&gt;[1][2]//&#39;&#39;, $v-&gt;[2][3]//&#39;&#39;,
  20. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  21. $v-&gt;[0][3]//&#39;&#39;, $v-&gt;[1][3]//&#39;&#39;, $v-&gt;[2][3]//&#39;&#39;
  22. .
  23. if (0) { # This is just for checking out our format
  24. # Test format
  25. # clear the columns at the beginning of the loop
  26. $v=undef;
  27. # set values for the various lines
  28. $name=&#39;decline the in german&#39;;
  29. # set values to used in third column
  30. $v-&gt;[2]=[qw(das des dem das)];
  31. # set values to used in second column
  32. $v-&gt;[1]=[qw(die der der die)];
  33. # set values to used in first column
  34. $v-&gt;[0]=[qw(der des dem den)];
  35. {
  36. # Safely output the format STDOUT
  37. my $old_handle=select STDOUT;
  38. # This goes to $new_handle:
  39. write;
  40. # restore the perevious handle
  41. select $old_handle;
  42. };
  43. };
  44. my %HoHoA;
  45. sub read_csv {
  46. my ($filename,$tag,$values)=@_;
  47. open(my $FILE,&#39;&lt;&#39;,$filename)
  48. or die &quot;Could not open &#39;$filename&#39;! $!&quot;;
  49. my %HoA;
  50. while (&lt;$FILE&gt;) {
  51. chomp;
  52. my ($k,@value)=split /,/,$_,$values;
  53. $HoHoA{$k}{$tag}=\@value;
  54. }
  55. close($FILE);
  56. } # sub read_csv
  57. # Read in the data
  58. read_csv(&#39;file3.csv&#39;,&#39;MODIFIED_FILE2&#39;,5);
  59. read_csv(&#39;file2.csv&#39;,&#39;MODIFIED_FILE1&#39;,4);
  60. read_csv(&#39;file1.csv&#39;,&#39;BASE_FILE&#39;,4);
  61. #;warn Data::Dumper-&gt;new([\%HoHoA],[qw(*HoHoA)])-&gt;Deepcopy(1)-&gt;Indent(1)-&gt;Maxdepth(3)-&gt;Sortkeys(1)-&gt;Dump(),q{ };
  62. for my $key (sort keys %HoHoA) {
  63. # clear/set the values used in the format
  64. $name=$key;
  65. $v=undef;
  66. # Put the stuff in columns --- just for fun they&#39;re out of order
  67. $v-&gt;[2]=$HoHoA{$key}{&#39;BASE_FILE&#39;} # third column
  68. if (exists $HoHoA{$key}{&#39;BASE_FILE&#39;});
  69. $v-&gt;[1]=$HoHoA{$key}{&#39;MODIFIED_FILE1&#39;} # second column
  70. if (exists $HoHoA{$key}{&#39;MODIFIED_FILE1&#39;});
  71. $v-&gt;[0]=$HoHoA{$key}{&#39;MODIFIED_FILE2&#39;}; # first column
  72. {
  73. # Safely output the format STDOUT
  74. my $old_handle=select STDOUT;
  75. # This goes to $new_handle:
  76. write;
  77. # restore the perevious handle
  78. select $old_handle;
  79. };
  80. };
  81. __DATA__

which gives

  1. -----------------------------------------------------------
  2. Boszor
  3. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  4. ------------------------------------------------------------
  5. 91 91 91
  6. Mexico Mexico Mexico
  7. Chinese Chinese
  8. AB+
  9. -----------------------------------------------------------
  10. Dora
  11. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  12. ------------------------------------------------------------
  13. 34 34
  14. Malaysian Malaysian
  15. Malay Arab
  16. B-

In response to your post that was closed - modifying the subroutine "read_csv" will do what you desire. The updated version of read_csv look like:

  1. sub read_csv {
  2. my ($filename,$tag,$values)=@_;
  3. my $FILE;
  4. my $raw=do{
  5. open $FILE,&#39;&lt;&#39;,$filename
  6. or die &quot;Could not open &#39;$filename&#39;! $!&quot;;
  7. # discard the first three lines (header etc)
  8. &lt;$FILE&gt;,&lt;$FILE&gt;,&lt;$FILE&gt;;
  9. # slurp the rest
  10. local $/=undef;
  11. &lt;$FILE&gt;;
  12. };
  13. #;warn Data::Dumper-&gt;new([\$raw],[qw(*raw)])-&gt;Deepcopy(1)-&gt;Indent(1)-&gt;Maxdepth(3)-&gt;Sortkeys(1)-&gt;Dump(),q{ };
  14. # remove all of those -----&#39;s
  15. $raw =~ s{^[-]+$(\r?\n)?}{}gms;
  16. #warn Data::Dumper-&gt;new([\$raw],[qw(*raw)])-&gt;Deepcopy(1)-&gt;Indent(1)-&gt;Maxdepth(3)-&gt;Sortkeys(1)-&gt;Dump(),q{ };
  17. # Use $raw as the buffer to read from
  18. open $FILE,&#39;&lt;&#39;,\$raw;
  19. while (&lt;$FILE&gt;) {
  20. chomp;
  21. my ($k,@value)=split /,/,$_,$values;
  22. $HoHoA{$k}{$tag}=\@value;
  23. }
  24. close($FILE);
  25. } # sub read_csv

This yields

  1. -----------------------------------------------------------
  2. Boszor
  3. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  4. ------------------------------------------------------------
  5. 91 91 91
  6. Mexico Mexico Mexico
  7. Chinese Chinese
  8. AB+
  9. -----------------------------------------------------------
  10. Dora
  11. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  12. ------------------------------------------------------------
  13. 34 34
  14. Malaysian Malaysian
  15. Arab Malay
  16. B-
  17. -----------------------------------------------------------
  18. Queeny
  19. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  20. ------------------------------------------------------------
  21. 47
  22. Rusia
  23. Russian
  24. O+`
  25. -----------------------------------------------------------
  26. Sarah
  27. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  28. ------------------------------------------------------------
  29. 21 21
  30. Malaysian Indonesia
  31. Bugis Bugis`
  32. AB+
  33. -----------------------------------------------------------
  34. Szundi
  35. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  36. ------------------------------------------------------------
  37. 23 23 23
  38. German German German
  39. Indian Indian
  40. AB-
  41. -----------------------------------------------------------
  42. Tharani
  43. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  44. ------------------------------------------------------------
  45. 30
  46. Australia
  47. Malay
  48. O-
  49. -----------------------------------------------------------
  50. Tudor
  51. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  52. ------------------------------------------------------------
  53. 10 10 10
  54. Spain Spain Vietnam
  55. Chinese Chinese
  56. A+

In response to the OP's comment

  1. #!/usr/bin/env perl
  2. use strict;
  3. use warnings;
  4. use Data::Dumper;
  5. my $output=&#39;outputfile.csv&#39;;
  6. # declaring variables used in MyFORMAT
  7. my $name=&#39;&#39;;
  8. my $v=undef;
  9. # more on format https://perldoc.perl.org/perlform
  10. format MyFORMAT =
  11. -----------------------------------------------------------
  12. @&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
  13. $name
  14. MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE
  15. ------------------------------------------------------------
  16. #==================#===================#===================#
  17. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  18. $v-&gt;[0][0]//&#39;&#39;, $v-&gt;[1][0]//&#39;&#39;, $v-&gt;[2][0]//&#39;&#39;,
  19. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  20. $v-&gt;[0][1]//&#39;&#39;, $v-&gt;[1][1]//&#39;&#39;, $v-&gt;[2][1]//&#39;&#39;,
  21. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  22. $v-&gt;[0][2]//&#39;&#39;, $v-&gt;[1][2]//&#39;&#39;, $v-&gt;[2][3]//&#39;&#39;,
  23. @|||||||||||||||||||@|||||||||||||||||||@||||||||||||||||||
  24. $v-&gt;[0][3]//&#39;&#39;, $v-&gt;[1][3]//&#39;&#39;, $v-&gt;[2][3]//&#39;&#39;
  25. .
  26. # note the &quot;.&quot; which ends the format
  27. # NB nothing else can be on that line not even a comment
  28. my %HoHoA;
  29. sub read_csv {
  30. my ($filename,$tag,$values)=@_;
  31. my $FILE;
  32. my $raw=do{
  33. open $FILE,&#39;&lt;&#39;,$filename
  34. or die &quot;Could not open &#39;$filename&#39;! $!&quot;;
  35. # discard the first three lines (header etc)
  36. &lt;$FILE&gt;,&lt;$FILE&gt;,&lt;$FILE&gt;;
  37. # slurp the rest
  38. local $/=undef;
  39. &lt;$FILE&gt;;
  40. };
  41. #;warn Data::Dumper-&gt;new([\$raw],[qw(*raw)])-&gt;Deepcopy(1)-&gt;Indent(1)-&gt;Maxdepth(3)-&gt;Sortkeys(1)-&gt;Dump(),q{ };
  42. # remove all of those -----&#39;s
  43. $raw =~ s{^[-]+$(\r?\n)?}{}gms;
  44. #warn Data::Dumper-&gt;new([\$raw],[qw(*raw)])-&gt;Deepcopy(1)-&gt;Indent(1)-&gt;Maxdepth(3)-&gt;Sortkeys(1)-&gt;Dump(),q{ };
  45. # Use $raw as the buffer to read from
  46. open $FILE,&#39;&lt;&#39;,\$raw;
  47. while (&lt;$FILE&gt;) {
  48. chomp;
  49. my ($k,@value)=split /,/,$_,$values;
  50. $HoHoA{$k}{$tag}=\@value;
  51. }
  52. close($FILE);
  53. } # sub read_csv
  54. # Read in the data building a Hash of Hashes of Arrays
  55. # with the key of the outer hash being the ID
  56. # and the key of the inner hash being the tag (ie: &#39;BASE_FILE&#39; etc)
  57. read_csv(&#39;file3.csv&#39;,&#39;MODIFIED_FILE2&#39;,5);
  58. read_csv(&#39;file2.csv&#39;,&#39;MODIFIED_FILE1&#39;,4);
  59. read_csv(&#39;file1.csv&#39;,&#39;BASE_FILE&#39;,4);
  60. #;warn Data::Dumper-&gt;new([\%HoHoA],[qw(*HoHoA)])-&gt;Deepcopy(1)-&gt;Indent(1)-&gt;Maxdepth(3)-&gt;Sortkeys(1)-&gt;Dump(),q{ };
  61. # Open a handle to $output
  62. open my $MyHANDLE,&#39;&gt;&#39;,$output
  63. or die &quot;Could not open &#39;$output&#39;! $!&quot;;
  64. # Associate the handle with its format
  65. # More on &quot;-&gt;format name&quot; https://perldoc.perl.org/perlvar#HANDLE-%3Eformat_name(EXPR)
  66. # note - because the format is invariant within the loop we can set it here
  67. $MyHANDLE-&gt;format_name(&#39;MyFORMAT&#39;);
  68. for my $key (sort keys %HoHoA) {
  69. # clear/set the values used in the format
  70. $name=$key;
  71. $v=undef;
  72. # Put the stuff in columns --- just for fun they&#39;re out of order
  73. $v-&gt;[2]=$HoHoA{$key}{&#39;BASE_FILE&#39;} # third column
  74. if (exists $HoHoA{$key}{&#39;BASE_FILE&#39;});
  75. $v-&gt;[1]=$HoHoA{$key}{&#39;MODIFIED_FILE1&#39;} # second column
  76. if (exists $HoHoA{$key}{&#39;MODIFIED_FILE1&#39;});
  77. $v-&gt;[0]=$HoHoA{$key}{&#39;MODIFIED_FILE2&#39;}; # first column
  78. # Associate the handle with its format
  79. # More on &quot;-&gt;format name&quot; https://perldoc.perl.org/perlvar#HANDLE-%3Eformat_name(EXPR)
  80. # note - because the format is invariant within the loop it has been move outside the loop
  81. #$MyHANDLE-&gt;format_name(&#39;MyFORMAT&#39;);
  82. # More on write https://perldoc.perl.org/functions/write
  83. write $MyHANDLE;
  84. };
  85. # Close the handle
  86. close $MyHANDLE
  87. or die &quot;Could not open &#39;$output&#39;! $!&quot;;
  88. __DATA__

答案2

得分: 1

以下是您提供的内容的翻译:

您正在查看您的数据记录,希望将其格式化为列,但您的输出媒体是基于行的。您需要将您的列式数据转换为适合您的媒体的输出。

使用 strictwarnings

所有 Perl 5 代码都应启用 strict 严格模式,并且最好使用 warnings 警告模式,特别是如果您需要帮助。strict 严格模式应该会为您提供一些关于出错原因的提示。在您的代码中启用 strict 将产生多个编译错误。

  1. $ perl -c -Mstrict -Mwarnings -wl foo.pl
  2. 全局符号 "$class_MODIFIED_FILE2" 需要显式包名称您是否忘记声明 "my $class_MODIFIED_FILE2"?) foo.pl 44
  3. 全局符号 "$class_MODIFIED_FILE1" 需要显式包名称您是否忘记声明 "my $class_MODIFIED_FILE1"?) foo.pl 44
  4. 全局符号 "$class_MODIFIED_FILE2" 需要显式包名称您是否忘记声明 "my $class_MODIFIED_FILE2"?) foo.pl 47
  5. 全局符号 "$class_MODIFIED_FILE2" 需要显式包名称您是否忘记声明 "my $class_MODIFIED_FILE2"?) foo.pl 63
  6. foo.pl 存在编译错误

您看到这个错误的原因是因为您尝试在声明变量之前使用它们。由于 Perl 是过程性的,它按行执行;它无法打印尚未声明的内容。

使用 CPAN 模块

最简单的解决方法是使用现有的 CPAN 模块之一。Data::Format::Pretty::Console 可以以列格式输出您的记录。其他流行的 CPAN 选项包括 Text::TableText::ASCIITable

考虑您的输出

这个问题本质上不是一个 Perl 问题,而是一个数据/格式化问题。由于您的目标输出媒体(ASCII 终端)基于行,您必须逐行打印。

如果您想在没有模块的情况下执行此操作,您必须考虑逐行打印。

以下是我认为可以实现您想要的效果的工作程序:

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. my %HoA = (
  5. MODIFIED_FILE2 => {
  6. Dora => [qw(34 Malaysian Malay B-)],
  7. Boszor => [qw(91 Mexico Chinese AB+)],
  8. },
  9. MODIFIED_FILE1 => {
  10. Dora => [qw(34 Malaysian Arab)],
  11. Boszor => [qw(91 Mexico Chinese)],
  12. },
  13. BASE_FILE => {
  14. Boszor => [qw(91 Mexico Chinese)],
  15. },
  16. );
  17. my @columns = qw(MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE);
  18. # 注意使用 sort 以确保一致的输出
  19. for my $name (sort keys %{ $HoA{MODIFIED_FILE2} }) {
  20. print "-" x 60, "\n";
  21. print "$name\n";
  22. printf "%-20s" x @columns, @columns;
  23. print "\n";
  24. print "-" x 60, "\n";
  25. for my $idx (0..3) { # 年龄、国家、种族、血型
  26. for my $column (@columns) {
  27. printf "%-20s", $HoA{$column}{$name}[$idx] // q{};
  28. }
  29. print "\n";
  30. }
  31. print "\n";
  32. }

请注意 for(或 foreach)循环 - 您必须从内到外考虑它们。您想要在同一上打印每一列,这就是为什么列是最内层的循环,而在该循环中不打印换行符的原因。

接下来的循环是索引,因为您想要按索引打印列的组(最内层循环),并在每个组的末尾打印换行符。

最后,$name 是最外层的循环,因为您想要按名称打印每组数据。

此代码仅检查 $HoA{MODIFIED_FILE2} 中的名称,这就是您的代码正在做的事情。如果您实际上想要检查所有名称,您可能希望使用 mapList::Util::uniq

英文:

You are looking at your data in terms of records, which you want formatted as columns, but your output medium is row (line) based. You have to transform your columnar data into an output suitable for your medium.

Use strict and warnings

All Perl 5 code should enable the strict pragma, and ideally use warnings pragma especially if you are asking for help. The strict pragma would have given you some hints about what went wrong. Enabling strict on your code yields several compilation errors.

  1. $ perl -c -Mstrict -Mwarnings -wl foo.pl
  2. Global symbol &quot;$class_MODIFIED_FILE2&quot; requires explicit package name (did you forget to declare &quot;my $class_MODIFIED_FILE2&quot;?) at foo.pl line 44.
  3. Global symbol &quot;$class_MODIFIED_FILE1&quot; requires explicit package name (did you forget to declare &quot;my $class_MODIFIED_FILE1&quot;?) at foo.pl line 44.
  4. Global symbol &quot;$class_MODIFIED_FILE2&quot; requires explicit package name (did you forget to declare &quot;my $class_MODIFIED_FILE2&quot;?) at foo.pl line 47.
  5. Global symbol &quot;$class_MODIFIED_FILE2&quot; requires explicit package name (did you forget to declare &quot;my $class_MODIFIED_FILE2&quot;?) at foo.pl line 63.
  6. foo.pl had compilation errors.

The reason you see this is because you are trying to use variables before you declare them. Since Perl is procedural, it goes line-by-line; it can't print what hasn't been declared yet.

Use a CPAN module

The simplest answer for this is to use one of several existing CPAN modules. Data::Format::Pretty::Console can output your records in columnar format. Other popular CPAN options include Text::Table, Text::ASCIITable.

Think about your output

This question is not fundamentally a Perl question, but a data/formatting question. Since your target output medium (an ASCII terminal) is based on rows, you have to print one row at a time.

If you want to do this without a module, you have to think in terms of printing one line at a time.

Here is a working program that I think accomplishes what you want:

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. my %HoA = (
  5. MODIFIED_FILE2 =&gt; {
  6. Dora =&gt; [qw(34 Malaysian Malay B-)],
  7. Boszor =&gt; [qw(91 Mexico Chinese AB+)],
  8. },
  9. MODIFIED_FILE1 =&gt; {
  10. Dora =&gt; [qw(34 Malaysian Arab)],
  11. Boszor =&gt; [qw(91 Mexico Chinese)],
  12. },
  13. BASE_FILE =&gt; {
  14. Boszor =&gt; [qw(91 Mexico Chinese)],
  15. },
  16. );
  17. my @columns = qw(MODIFIED_FILE2 MODIFIED_FILE1 BASE_FILE);
  18. # NOTE use sort to guarantee consistent output
  19. for my $name (sort keys %{ $HoA{MODIFIED_FILE2} }) {
  20. print &quot;-&quot; x 60, &quot;\n&quot;;
  21. print &quot;$name\n&quot;;
  22. printf &quot;%-20s&quot; x @columns, @columns;
  23. print &quot;\n&quot;;
  24. print &quot;-&quot; x 60, &quot;\n&quot;;
  25. for my $idx (0..3) { # age, country, ethincity, blood type
  26. for my $column (@columns) {
  27. printf &quot;%-20s&quot;, $HoA{$column}{$name}[$idx] // q{};
  28. }
  29. print &quot;\n&quot;;
  30. }
  31. print &quot;\n&quot;;
  32. }

Notice the for (or foreach) loops - you have to think about them from the inside out. You want to print each column on the same line, which is why column is the inner-most loop and there is no newline printed in that loop.

The next loop out is the index, because you want to print groups of columns (the inner-most loop) per index, along with a newline at the end of each.

Finally, the $name is the outermost loop, because you want to print each group of data per name.

This code only checks the names in $HoA{MODIFIED_FILE2}, which is what your code was doing. If you actually meant to check all of them, you would probably want to use a map with a List::Util::uniq.

huangapple
  • 本文由 发表于 2023年7月18日 16:00:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76710639.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定