저장 한 데이터가있는 파일이 있습니다. 이제 결과를 새 파일로 인쇄하고 싶습니다.
예를 들어 다음 예제를 보자 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
이것이 가능한가? 선을 위치 에서이 위치로 설정하고 싶습니다.
답변
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입니다.
답변
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