하나고대의initramfs 내부의 버전에서는 ipconfig
사용자 입력이 콜론으로 구분된 요소를 최대 7개까지만 제공해야 합니다. 예를 들면 다음과 같습니다.
ip=client-ip:server-ip:gw-ip:netmask:hostname:device:autoconf
ipconfig
사용자가 7개 이상의 요소를 제공하면 오류가 발생합니다.
따라서 추가(2개의 DNS 확인자)를 잘라야 합니다.
subshell
예를 들어 다음과 같이 내부에서 이 작업을 수행할 수 있습니다 cut
.
validated_input=$(echo ${user_input} | cut -f1,2,3,4,5,6,7 -d:)
매개변수 확장/대체를 사용하여 cut
이와 같은 코드를 어떻게 작성할 수 있습니까?(b)ash
아니요:
- 서브셸/하위 프로세스 시작(파이프라인)
- IFS - 인수/파괴
(1) 속도 이후 참조Cut/awk 대신 bash 변수 대체 사용(2) 학습.
즉, n(7번째) 문자 발생을 찾고 거기에서 문자열 끝까지 모든 것을 제거/자르려면 어떻게 해야 합니까?
답변1
이는 매개변수 확장만 사용합니다.
${var%:"${var#*:*:*:*:*:*:*:}"}
예:
$ var=client-ip:server-ip:gw-ip:netmask:hostname:device:autoconf:morefields:another:youwantanother:haveanother:
$ echo "${var%:"${var#*:*:*:*:*:*:*:}"}"
client-ip:server-ip:gw-ip:netmask:hostname:device:autoconf
후행 수정을 제안한 ilkkachu에게 감사드립니다 :
!
${parameter#word}
${parameter##word}
파일 이름 확장과 마찬가지로 단어가 확장되어 패턴을 생성합니다(파일 이름 확장자 참조). 패턴이 매개변수 확장 값의 시작과 일치하는 경우 확장 결과는 가장 짧은 일치 패턴("#"의 경우) 또는 가장 긴 일치 패턴("##"의 경우)이 있는 매개변수 확장 값이 됩니다. 제거됨. 매개변수가 "@" 또는 "인 경우'를 사용하면 각 위치 인수에 패턴 제거 작업이 차례로 적용되고 확장이 결과 목록이 됩니다. 매개 변수가 배열 변수인 경우 아래 첨자는 "@" 또는 "'를 실행하면 배열의 각 멤버에 패턴 삭제 작업이 차례로 적용되고 확장이 결과 목록이 됩니다.
이것은 일치를 시도합니다시작매개변수가 있으면 삭제됩니다.
예:
$ var=a:b:c:d:e:f:g:h:i
$ echo "${var#a}"
:b:c:d:e:f:g:h:i
$ echo "${var#a:b:}"
c:d:e:f:g:h:i
$ echo "${var#*:*:}"
c:d:e:f:g:h:i
$ echo "${var##*:}" # Two hashes make it greedy
i
${parameter%word}
${parameter%%word}
파일 이름 확장과 마찬가지로 단어가 확장되어 패턴을 생성합니다. 패턴이 매개변수 확장 값의 후행 부분과 일치하는 경우 확장 결과는 가장 짧은 일치 패턴("%" 케이스) 또는 가장 긴 일치 패턴("%%" 케이스)이 있는 매개변수 값이 제거됩니다. 매개변수가 "@" 또는 "인 경우'를 사용하면 각 위치 인수에 패턴 제거 작업이 차례로 적용되고 확장이 결과 목록이 됩니다. 매개 변수가 배열 변수인 경우 아래 첨자는 "@" 또는 "'를 실행하면 배열의 각 멤버에 패턴 삭제 작업이 차례로 적용되고 확장이 결과 목록이 됩니다.
이것은 일치를 시도합니다끝매개변수가 있으면 삭제됩니다.
예:
$ var=a:b:c:d:e:f:g:h:i
$ echo "${var%i}"
a:b:c:d:e:f:g:h:
$ echo "${var%:h:i}"
a:b:c:d:e:f:g
$ echo "${var%:*:*}"
a:b:c:d:e:f:g
$ echo "${var%%:*}" # Two %s make it greedy
a
그래서 대답은 다음과 같습니다.
${var%:"${var#*:*:*:*:*:*:*:}"}
${var#...}
( 끝에서 제거할 리터럴 문자열(패턴이 아닌)로 처리되도록 주변 따옴표에 유의하십시오 $var
.)
적용 대상:
var=client-ip:server-ip:gw-ip:netmask:hostname:device:autoconf:morefields:another:youwantanother:haveanother:
${var#*:*:*:*:*:*:*:}
=morefields:another:youwantanother:haveanother:
내부 확장 ${var%: ... }
은 다음과 같습니다.
${var%:morefields:another:youwantanother:haveanother:}
그래서 당신은 나에게 이렇게 말하고 있습니다.
client-ip:server-ip:gw-ip:netmask:hostname:device:autoconf:morefields:another:youwantanother:haveanother:
하지만 :morefields:another:youwantanother:haveanother:
끝부분을 잘라주세요.
Bash 참조 매뉴얼(3.5.3)
답변2
정규 표현식을 사용하세요:
$ var=a:b:c:d:e:f:g:h:i:j:k:l
$ [[ $var =~ ([^:]*:){6}([^:]*) ]] && echo "${BASH_REMATCH[0]}"
a:b:c:d:e:f:g
이는 표준 셸에서 작동합니다.
#!/bin/sh
var=a:b:c:d:e:f:g:h:i:j:k:l
while true; do
case "$var" in
*:*:*:*:*:*:*:*) var=${var%:*} ;;
*) break ;;
esac
done
echo "$var"
IFS
또는 기간 설정을 허용하는 경우 read
:
$ IFS=: read -a arr <<< "$var"
$ arr=("${arr[@]:0:7}")
$ echo "${arr[@]}"
a b c d e f g
$ printf "%s:%s:%s:%s:%s:%s:%s\n" "${arr[0]}" "${arr[1]}" "${arr[2]}" "${arr[3]}" "${arr[4]}" "${arr[5]}" "${arr[6]}"
a:b:c:d:e:f:g
답변3
존재하다 zsh
:
$ ip=client-ip:server-ip:gw-ip:netmask:hostname:device:autoconf:x:y:z
$ echo ${(j(:))${"${(@s(:))ip}"[1,7]}}
client-ip:server-ip:gw-ip:netmask:hostname:device:autoconf
${(s(:))var}
나뉘다:
"${(@)...}"
: 빈 요소를 유지해야 합니다(예:"$@"
).${var[1,7]}
요소 1~7${(j(:))var}
요소 추가:
아니면 이렇게 할 수도 있습니다:
$ set -o extendedglob
$ echo ${(M)ip##([^:]#:)(#c0,6)[^:]#}
client-ip:server-ip:gw-ip:netmask:hostname:device:autoconf
${var##pattern}
ksh와 마찬가지로 패턴과 일치하는 가장 긴 선행 부분을 제거합니다.(M)
: 다음으로 확장중간 사이즈부품을 벗기지 말고 고치세요.x#
: 0개 이상의x
s (예: regexp*
)(#c0,6)
0에서 6까지의 이전 원자( ksh와 유사{x,y}(...)
)