awk를 사용하여 위치 매개변수 뒤의 모든 내용을 인쇄하는 방법이 있나요? 다음 명령으로 인쇄하고 싶은 것은 "p4 p5 p6 p7"입니다.
echo p1 p2 p3 p4 p5 p6 p7 | awk '{print $4...}'
또한 두 위치 매개변수 사이에 인쇄하는 것도 가능합니까? 다음은 "p4 p5 p6"을 인쇄합니다.
echo p1 p2 p3 p4 p5 p6 p7 | awk '{print $4...$6}'
정규식을 사용하고 다음을 입력하는 것을 피하고 싶습니다: awk '{print $4" "$5" "$6}'
답변1
awk
(일종의 루프를 사용하지 않고) 이 작업을 수행하는 것은 불가능하지만 perl
가능합니다.
그러나 perl
배열은 0부터 시작합니다(그리고 awk
배열 인덱싱은 1부터 시작합니다).
예를 들어 다음과 같이 자동 분할을 위해 perl
' 옵션을 사용합니다.-a
awk
$ echo p1 p2 p3 p4 p5 p6 p7 | perl -lane 'print "@F[3..$#F]";'
p4 p5 p6 p7
$ echo p1 p2 p3 p4 p5 p6 p7 | perl -lane 'print "@F[2,4,6]";'
p3 p5 p7
$ echo p1 p2 p3 p4 p5 p6 p7 | perl -lane 'print "@F[1..3]";'
p2 p3 p4
참고: -l
Perl의 줄 끝 자동 처리를 켜고 -n
자동 출력 없이 한 줄씩 입력을 처리하는 루프로 래핑합니다(sed의 -n 옵션과 유사합니다. -p
동일한 작업을 수행하지만 다음 내용을 자동으로 인쇄합니다. 각 입력 줄이 확인되었습니다. 및/또는 나머지 스크립트에 의해 수정됨). 바라보다 man perlrun
.
배열 및 배열 분할에 대한 자세한 내용은 man perldata
또는를 참조하세요.perldoc perlvar
배열 조각은 큰따옴표로 묶인 문자열 안에 인쇄되므로 $"
aka 값을 사용하여 $LIST_SEPARATOR
배열 요소를 구분합니다. 큰따옴표로 묶인 문자열 외부에서 인쇄/사용되는 경우 요소 사이에 구분 기호가 전혀 없습니다. LIST_SEPARATOR를 확인 man perlvar
하거나 perldoc perlvar
검색하세요.
-F
마지막으로, 필드 구분 기호가 공백(PCRE에서)이 아닌 경우 Perl의 options 을 사용 \s+
하거나 직접 분할하세요. 예를 들어
$ echo "p1:p2:p3:p4:p5:p6:p7" | perl -F: -lane 'print "@F[0..4]";'
p1 p2 p3 p4 p5
$ echo "p1:p2:p3:p4:p5:p6:p7" | perl -lne '@F=split /:/; print "@F[0..4]";'
p1 p2 p3 p4 p5
답변2
매개변수가 공백으로 확실하게 구분되어 있는 경우 다음을 사용할 수 있습니다 cut
.
echo p1 p2 p3 p4 p5 p6 p7 | cut -d' ' -f4- # For p4 onwards
echo p1 p2 p3 p4 p5 p6 p7 | cut -d' ' -f4-6 # For p4 to p6
인수를 공백으로 구분하려면 인수를 구문 분석하는 방식이 awk
확실히 더 복잡해집니다. 제가 말하는 내용과 위의 내용이 원하는 효과를 항상 얻지 못할 수 있는 방법에 대한 예를 보려면 다음을 시도해 보세요.
printf '%s ' p1 p2 p3 p4 p5 p6 p7 | cut -d' ' -f4-
printf '%s ' p1 p2 p3 p4 p5 p6 p7 | cut -d' ' -f4-6
cut
치료 되고 있는 모습을 보실 수 있습니다각구분 기호로 공백을 사용하는 것이지 이와 같은 구분 기호로 연속 공백을 사용하는 것이 아닙니다 awk
. awk
for 루프를 사용하여 원하는 것을 강제할 수 있습니다 .
echo p1 p2 p3 p4 p5 p6 p7 | awk '{for (a=4;a<=NF;a++) {printf "%s ", $a} printf "\n"}'
그러나 이렇게 하면 줄 끝에 후행 공백이 남습니다. 이 문제는 해결될 수 있지만 상황은 점점 더 혼란스러워질 것입니다. 요구 사항에 따라 이 cut
명령이 괜찮을 수도 있습니다.
답변3
awk의 분할 기능을 사용하여 수행하는 방법은 다음과 같습니다(이전 답변에 따르면 for 루프가 필요함).
설명하다:
"sub_0" - variable to contain desired output ($0 substring)
"beg" - 1st desired field (references 4th element in "pn_ary" array)
(external "$beg" shell variable passed into awk (internal "beg" variable)
"end" - # of fields in $0 (split function loads each field in $0 as a "pn_ary[n]" element ("1-n"))
"split(s,a,sep) - "s": string, "a": array, "sep": seperator (splits "s" per "sep", loads "a")
("split" returns # of elements loaded into "pn_ary" array into "end" variable)
"FS" - awk system Field Seperator variable
"[:graph:]" - Posix bracket expression for visible ASCII chars in range "[\x21-\x7E]"
통사론:
beg="4"
echo "p1 p2 p3 p4 p5 p6 p7" |\
awk '{sub_0="";end=split($0,pn_ary,FS)
for (i=beg;i<=end;i++) {sub_0=sub_0""FS""pn_ary[i]}
print substr(sub_0,match(sub_0,"[:graph:]"))
}' beg="$beg"
산출:
p4 p5 p6 p7