파일을 살펴보고 특정 줄에서 텍스트를 인쇄하십시오.


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 번째 문자와 3 번째 줄의 4 ~ 8 번째 문자 만 어떻게 데이터를 가져올 수 있습니까? 출력은 다음과 같습니다.

Ethernet
t6 ad

이것이 가능한가? 선을 위치 에서이 위치로 설정하고 싶습니다.

답변:


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전용 ((가)의 무엇을하는 1 라인에서 실행됩니다 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각 라인을. 스크립트는 이전과 동일 기본적인 생각이다. $.우리가 줄 번호가 하나인지 확인 있도록 변수가 현재의 행 번호를 보유 1하거나 3하는 경우, 그리고 따라서 대체를 실행하고 그렇지 않으면 건너 뛰십시오. 따라서 나머지 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은 첫 번째 줄의) 에서 세고 세 번째 줄의 경우 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

이것은 <쉘 연산자를 사용 하여 입력 스트림을 입력 파일에서 파이썬 프로세스로 리디렉션합니다. 파이썬의 문자열은 인덱스가 0이므로 원하는 문자 수를 모두 1 씩 이동해야합니다.

휴대용 쉘 방식

이것은 ksh,, dash에서 작동합니다 bash. 쉘 유틸리티에만 의존하고 외부는 사용하지 않습니다.

#!/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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.