浏览文件并从特定行打印文本


8

我有一个保存数据的文件。现在,我想将结果打印到一个新文件中。

例如,让我们来看这个例子randomlog.log

Link encap:Ethernet HWaddr 08:00:00:00:00:67
inet addr:10.10.10.10 Bcast:10.10.10.10 Mask:255.255.255.0
inet6 addr: fe80::casf:sdfg:23ra:dg12/64 Scope:Link

如何仅从第一行的第12到20个字符然后从第三行的第4到8个字符获取数据?输出看起来像这样:

Ethernet
t6 ad

这可能吗?我要设置线并从位置设置到此位置。

Answers:


9

这是一种sed方法:

$ sed -nE '1s/.{11}(.{8}).*/\1/p; 3s/.{3}(.{4}).*/\1/p' file  
Ethernet
t6 a

说明

-n禁止常规输出(正常是打印每个输入线)时告知,使其只打印。在-E启用扩展正则表达式。

sed脚本有两个命令,都使用替代运算符(s/original/replacement/)。该1s/.{11}(.{8}).*/\1/p会一号线(这是唯一的运行1s一样),并且将匹配1号线的11个字符(.{11}),然后将其抓住下一个8( (.{8}),括号是一个“捕获组”),然后一切,直到行(.*)的末尾。所有这一切都将替换为捕获组中的所有内容(\1;如果有第二个捕获组,则为\2等等)。最后,p末尾的(s/foo/bar/p)使替换后的行被打印。这导致仅输出目标8个字符。

第二个命令是相同的基本思想,只不过它仅在第三行(3s)上运行,并且将从第4行开始保留4个字符。


您也可以使用以下方法执行相同的操作perl

$ perl -ne 'if($.==1){s/.{11}(.{8}).*/\1/}
            elsif($.==3){s/.{3}(.{4}).*/\1/}
            else{next}; print; ' file 
Ethernet
t6 a

说明

-ne意思是“逐行读取输入文件中的行,并申请给出的脚本-e到每一行。该脚本是相同的基本想法之前该$.变量保存当前的行号,以便我们检查,如果行号或者是13,如果因此,运行替换,否则跳过,因此print将仅对这两行运行,因为将跳过所有其他行。


当然,这是Perl,所以TIMTOWTDI

$ perl -F"" -lane '$. == 1 && print @F[11..19]; $.==3 && print @F[3..6]' file 
Ethernet 
t6 a

说明

这里的-a意思是“将每个输入行分割在给定的字符上-F并另存为数组@F。由于给定的字符为空,因此会将输入行的每个字符另存为元素@F。然后,我们打印元素11-19(0第1行的数组从)开始计数,第3行的数组从3-7 开始计数。


1

awk方法:

$ awk 'NR==1{print substr($0,12,8)};NR==3{print substr($0,4,4)}' input.txt  
Ethernet
t6 a

用途NR,用于确定线路(在AWK术语-记录)数,并且相应地打印已子串的行的。substr()功能采用格式

substr(string,starting position,how much offset) 

蟒蛇

$ python -c 'import sys                                                                                                                                                
> for index,line in enumerate(sys.stdin,1):                                                                                                                            
>     if index == 1:
>          print line[11:19]
>     if index == 3:
>          print line[3:7]' < input.txt
Ethernet
t6 a

这使用<shell运算符将输入流从输入文件重定向到python进程。请注意,Python中的字符串是0索引的,因此您需要将所需的字符数全部移1。

便携式外壳方式

这部作品在kshdashbash。仅依靠shell实用程序,不依赖外部。

#!/bin/sh

rsubstr(){
    i=0;
    while [ $i -lt  $2 ];
    do
        rmcount="${rmcount}?"
        i=$(($i+1))
    done;
    echo "${1#$rmcount}"
}

lsubstr(){
    printf "%.${2}s\n" "$1"
}

line_handler(){
    case $2 in
        1) lsubstr "$(rsubstr "$1" 11)" 8 ;;
        3) lsubstr "$(rsubstr "$1" 3)" 5 ;;
    esac
}

readlines(){
    line_count=1
    while IFS= read -r line;
    do
        line_handler "$line" "$line_count"
        line_count=$(($line_count+1))
    done < $1
}

readlines "$1"

它的工作原理如下:

$ ./get_line_substrings.sh input.txt                                                                                                                                   
Ethernet
t6 ad
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.