변수를 grep하고 1을 추가합니다.

변수를 grep하고 1을 추가합니다.

앞에 0이 포함된 변수가 있는데 이 변수와 동일한 변수에 1을 더한 값을 grep하고 싶습니다. 여러 번 시도했지만 오류가 발생했습니다. 이것이 내가 하고 싶은 일이다:

read var
newvar=$(($var +1))
grep '$var' /some/dir
grep '$newvar' /some/dir

내 코드에 뭔가 문제가 있는 것 같아요. 나는 또한 다음과 같은 몇 가지 테스트를 시도했습니다.

#!/bin/bash
echo "enter number"
read number
newnumber=$(($number + 1))
echo "$newnumber"

이로 인해 오류가 발생했습니다 value too great for base (error token is. 내가 이렇게 하면:

 #!/bin/bash
echo "enter number"
read number
number=""
newnumber=$(($number + 1))
echo "$newnumber"

그러면 항상 1이 출력됩니다.

내 시도에 어떤 문제가 있으며 내가 원하는 것을 어떻게 할 수 있나요?

답변1

잘못된 따옴표를 사용하고 있습니다. 작은 따옴표는 ''표현식(및 이전 형식)의 확장을 방지합니다. 대신 큰따옴표를 사용하세요. 이 경우 숫자라고 확신한다면 필요하지 않습니다.$$var$(command)`command`""어느인용 부호.

두 번째 질문에는... 앞에 0을 사용합니까? 이는 8진수를 나타내므로 숫자 합계가 작동 8하지 9않습니다.

답변2

긱 드래곤첫 번째 시도가 실패한 이유를 이미 설명했습니다. 수행하려는 작업에 대한 몇 가지 추가 팁은 다음과 같습니다.

비슷한 숫자를 찾고 있다면 을 42일치시키고 싶겠지만 또는 042는 일치시키지 않을 것입니다 . 이를 달성하려면 더 발전된 정규식만 있으면 됩니다. 앞에 0이 없는 숫자(정수, 양수, 소수 표현)가 포함된 경우 앞에 줄의 시작 부분이나 숫자가 아닌 문자가 오는 문자와 그 뒤에 오는 동일한 문자를 찾습니다 . 앞에 0이 추가로 허용됩니다. 이 옵션은 현대 정규식 구문(더 이상하고 덜 강력한 과거 구문과 반대)을 사용하고 있음을 나타냅니다.1042421$newnumber$newnumber0*-Egrep

grep -E "(^|[^0-9])0*$newnumber(\$|^[0-9])" /path/to/file

$((10#$newnumber))Bash에서 앞에 0이 올 수 있는 숫자를 구문 분석하려면 강제 십진수 해석을 사용할 수 있습니다 . 다른 쉘에서는 상황이 약간 더 복잡합니다. 특정 접두사 없이 변수 값을 얻는 쉘 구조 ${var#prefix}와 유사한 접미사 구조가 있지만 다음과 같이 "가능한 가장 긴 문자 시퀀스" ${var%suffix}를 지정할 수 있는 방법은 없습니다. 0제거할 접두사. 하지만 두 단계로 수행할 수 있습니다. 먼저 var선행 0이 아닌 부분을 가져와 이를 제거된 접두사로 사용합니다. 0 앞에 오지 않는 부분은 var0이 아닌 것부터 시작하는 가장 긴 접미사입니다. 즉 ${var%%[!0]*}, 이중 정밀도는 %패턴과 일치하는 가장 긴 접미사를 취하는 것을 의미하고, 단정밀도는 %가장 짧은 접미사를 취하는 것을 의미합니다.

read number
number=${number#${number%%[!0]*}}

추가 설명: grep REGEXP /some/file단일 파일 검색 /some/file. 디렉토리의 모든 파일을 검색하려면 쉘이 파일 목록을 생성하도록 하십시오: grep REGEXP /some/dir/*디렉토리 및 해당 하위 디렉토리의 모든 파일을 재귀적으로 검색하려면 옵션을 전달하여 재귀적 -r으로 grep만드십시오 grep -r REGEXP /some/dir.

답변3

Geekosaur가 말했듯이 잘못된 인용문을 사용하고 있습니다. 쉘이 값에 대한 변수 참조를 확장하도록 하려면 큰따옴표를 사용하십시오.

둘째, 이중 괄호 안의 수학이 잘못되었습니다. $(( )) 구문 내부의 변수 참조에는 $가 필요하지 않습니다.

#!/bin/bash
echo "enter number"
read number
newnumber=${number#${number%%[!0]*}}
newnumber=$((newnumber + 1))
echo "$number changes to $newnumber"

이 두 가지 변경 사항은 원본 버전에서도 효과가 있었습니다...

read var
newvar=${var#${var%%[!0]*}}
newvar=$((newvar + 1))
printf -v newvar "%02d" "$newvar"
grep "$newvar" /some/dir

고쳐 쓰다출력 형식을 지정하는 행을 추가했습니다 printf. 업데이트 20으로 채워진 숫자 입력에 대한 수정 사항이 추가되었습니다. 이제 이것은 완전한 예가 될 것입니다.

답변4

여러 가지 부분 답변:

앞에 0이 붙은 숫자 v1을 처리하는 방법:

newvar=$(printf '%s + 1\n' "$var" | bc)

또는 동등하게,

newvar=$(bc <<< "$var + 1")

bc앞에 0이 붙은 숫자는 8진수로 간주되지 않기 때문입니다 .

내가 아는 한, bc쉘 이스케이프 기능이 없는 것으로 보이므로 이는 코드 주입 취약점을 생성하지 않습니다. (아마 뭔가 간과하고 있는 것 같습니다.) 질문에는 "bash only"라고 쓰여 있지 않습니다.

앞에 0이 붙은 숫자 v2를 처리하는 방법:

newvar=$((1$var - 10000 + 1))

분명히 이것은 트릭을 사용하는 것 같습니다.야오리가 하고 싶은 일: 1접두사 로0042 문자열 연산으로서,1004210진수로 처리된 문자열을 얻게 됩니다 . 이 구성에서는~ 해야 하다및 가  두 개의 별도 단위로 구문 분석된 다음 연결   되도록 포함합니다  $.$var1$var

입력값이 4자리인 것으로 알려진 경우(예  0042: ) 위 명령을 그대로 사용합니다. 다른 길이가 있는 경우(미리 알려짐) 10000위의 내용 1뒤에 적절한 개수의 0이 오도록 변경하세요.

만약 너라면아니요길이를 미리 알고 하세요.

pow10="1$(printf "%0${#var}d" 0)"

또는

pow10="1$(printf '%0*d' "${#var}" 0)"

이는 기본적으로 숫자가 4자리인 경우(예:  )를 생성하는 0042데 사용되며 , 이를 얻기 위해  앞에 a가 추가됩니다  . 그럼 해printf '%04d' 00000110000

newvar=$((1$var - pow10 + 1))

결과 에 newvar선행 0을 추가하는 방법:

마크의 대답사용할 수 있음을 나타냅니다.

printf -v newvar '%04d' "$newvar"

또는 동등하게,

newvar=$(printf '%04d' "$newvar")

$newvar합계가 4자리가 되도록 앞에 0을 충분히 추가합니다 . 길이를 미리 모르는 경우 이전 섹션의 기술을 사용할 수 있습니다.

newvar="$(printf "%0${#var}d" "$newvar")"

또는

newvar="$(printf '%0*d' "${#var}" "$newvar")"

관련 정보