简体   繁体   English

如何使Perl打印字符串的前十行?

[英]How can I make Perl print first ten lines of a string?

I'm trying to show the first ten lines of a large string (first 10 lines of a paragraph). 我正在尝试显示大字符串的前十行(段落的前十行)。 I've tried to use: 我尝试使用:

 $lines = head-10 $string

I saw some examples that use while loops but my script can't facilicate that, I need it to be a variable. 我看到了一些使用while循环的示例,但是我的脚本无法实现这一点,我需要将其作为变量。

Next I tried to use: 接下来,我尝试使用:

 $string = perl -pe'$.>10&&last'

which gave me the desired result by typing 通过输入获得了理想的结果

String= "$(string | head -n10)"

Perl allows you to open a filehandle on a string. Perl允许您在字符串上打开文件句柄。 You can then use filehandle idioms to "read" the string. 然后,您可以使用文件句柄惯用法来“读取”字符串。

my $string = <<"HERE";
This is the first line
This is the second line
3rd
4th
5th
6th
seventh
one plus seventh
eighth
tenth minus one
tenth
should not go this far
way to far
okay stop now, srsly
This is the last line
HERE


open my $fh, '<:utf8', \ $string or die;
while( 0 .. 10 ) {
    print { STDOUT } scalar <$fh>;
    }
close $fh;

In this example, instead of a filename I give open a reference to a scalar. 在此示例中,我open了对标量的引用,而不是文件名。 Now I have a filehandle on that scalar. 现在,我在该标量上有一个文件句柄。

In the while , I use the flip-flop operator. while ,我使用触发器运算符。 It looks like the range operator, but in boolean context it's different. 它看起来像范围运算符,但在布尔上下文中则有所不同。 It is true when the first condition is true, and stays true until the second condition is true. 当第一个条件为true时为true,并在第二个条件为true之前保持为true。 That is, it turns on, stays on, then turns off. 也就是说,它先打开,然后保持,然后再关闭。

When you use number literals with the flip flop, it looks at the line number for the currently read filehandle (in this case $fh). 当您在触发器中使用数字文字时,它将查看当前读取的文件句柄的行号(在本例中为$ fh)。 So, we turn it on when the line number is 0 and turn it off when the line number is 10. That means that the loop doesn't execute when the line number is 10 because the condition is now false. 因此,我们在行号为0时将其打开,而在行号为10时将其关闭。这意味着当行号为10时,循环将不会执行,因为条件现在为假。 But, that's okay because that's actually line 11. 但是,没关系,因为实际上是第11行。

Or, you can do that with a counting for loop: 或者,你可以做到这一点与计数for循环:

open my $fh, '<:utf8', \ $string or die;
for( my $i = 0; $i <= 10; $i++ ) {
    print { STDOUT } scalar <$fh>;
    }
close $fh;

In both examples I use scalar <$fh> to get the next line because I used it inline with the print , a list context operator. 在两个示例中,我都使用scalar <$fh>来获取下一行,因为我将其与print一起使用,后者是一个列表上下文运算符。 I don't want all the lines. 我不要所有的线。 I surround the output handle in braces to set it apart from the rest of what's going on. 我将输出手柄括在括号中,以将其与其余所有操作区分开。

But, you're asking about it being in a bash script it looks like. 但是,您要问的是它看起来像是在bash脚本中。 Anything you can do in a "normal" perl program you can do in the argument to -e : 您可以在“ -e ”参数中执行“常规” perl程序中可以执行的任何操作:

perl -e 'open my $fh, q(<:utf8), \ $ARGV[0] or die;
    for( my $i = 0; $i <= 10; $i++ ) {
        print { STDOUT } scalar <$fh>;
        }
    close $fh;' string_arg

Try the following solution between >>>> START... and <<<< END... comments (The remainder is wrapper code to turn it into a standalone script for demo/testing purposes). >>>> START...<<<< END...注释之间尝试以下解决方案(其余为包装代码,将其转换为用于演示/测试目的的独立脚本)。 After the solution section, $s_start will contain the first 10 lines of $s_raw : 该解决方案后段, $s_start将包含第一个10行$s_raw

#!/usr/bin/perl
#
use warnings;

my (
      $n_lines
    , $s_raw
    , $s_start
    , $s_thisline
);

{ local $/ = undef; $s_raw = <DATA>; }

#>>>> START of core code section
$n_lines = 0;
open $fh_raw, "<", \$s_raw;
while ( ($n_lines < 10) && ($s_thisline = <$fh_raw>) ) {
    $s_start .= $s_thisline;
    $n_lines++;
}
close $fh_raw;
#<<<< END of core code section

print $s_start;
exit(0);

__DATA__
This is a test
with lots of lines
and
a bit
repetitive in nature
however
it 
serves the purpose
of demonstrating
the
code above
...(arbitrarily more stuff) ...

If you want to do this in the code, split the paragraph into a list, use an array slice to get the first 10 elements and join them back together again by adding the newlines back. 如果要在代码中执行此操作,请将段落拆分为一个列表,使用数组切片获取前10个元素,然后通过添加换行符将它们重新结合在一起。

#!/usr/bin/perl

use strict;
use warnings;


my $string = "line1
line2
line3
line4
line5
line6
line7
line8
line9
line10
line11
line12";

#  turn the lines into a list by splitting on newline
my @lines = split "\n", $string;

#  take an array slice of the first 10 list items and join them into a string
#  delimited by a newline
my $first_ten = join "\n", @lines[0 .. 9];

#  print your 10 lines
print $first_ten;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果第二行包含与第一行相同的匹配,如何打印2行? - How can I print 2 lines if the second line contains the same match as the first line? 如何让 Perl 和 Python 打印正在执行的程序的每一行? - How can I make Perl and Python print each line of the program being executed? 如何在unix中打印出包含特定String的文件的所有行 - How can I print out all lines of a file containing a specific String in unix 如何仅匹配模式的前N个实例,然后在每个模式后面打印行直到空白行? - How can I match only the first N instances of a pattern, then print lines following each pattern until a blank line? 我怎样才能使文件中的行变量? - how can i make the lines variable in a file? 如何一起打印四个文件的行? - How can I print the lines of four files together? 我如何从bash变量中回显/打印特定行 - how can I echo/print specific lines from a bash variable 如何在单独的行上打印多个图案 - How can I print multiple patterns on separate lines 使用Bash,如何打印.txt文件的第一行中包含特定字符串的整行? - With Bash, how to print the whole lines of a .txt file which contain, in their first section, a specific string? 我可以使用哪些标准命令有效地在命令行上打印排序输出的前几行? - What standard commands can I use to print just the first few lines of sorted output on the command line efficiently?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM