앞에 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이 추가로 허용됩니다. 이 옵션은 현대 정규식 구문(더 이상하고 덜 강력한 과거 구문과 반대)을 사용하고 있음을 나타냅니다.1042
421
$newnumber
$newnumber
0*
-E
grep
grep -E "(^|[^0-9])0*$newnumber(\$|^[0-9])" /path/to/file
$((10#$newnumber))
Bash에서 앞에 0이 올 수 있는 숫자를 구문 분석하려면 강제 십진수 해석을 사용할 수 있습니다 . 다른 쉘에서는 상황이 약간 더 복잡합니다. 특정 접두사 없이 변수 값을 얻는 쉘 구조 ${var#prefix}
와 유사한 접미사 구조가 있지만 다음과 같이 "가능한 가장 긴 문자 시퀀스" ${var%suffix}
를 지정할 수 있는 방법은 없습니다. 0
제거할 접두사. 하지만 두 단계로 수행할 수 있습니다. 먼저 var
선행 0이 아닌 부분을 가져와 이를 제거된 접두사로 사용합니다. 0 앞에 오지 않는 부분은 var
0이 아닌 것부터 시작하는 가장 긴 접미사입니다. 즉 ${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
문자열 연산으로서,10042
10진수로 처리된 문자열을 얻게 됩니다 . 이 구성에서는~ 해야 하다및 가 두 개의 별도 단위로 구문 분석된 다음 연결 되도록 포함합니다 $
.$var
1
$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' 0
0000
1
10000
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")"