입력은 다음과 같은 파일 이름이 됩니다.
A-B-000001-C
A-B-000002-C
.....
.....
A-B-999999-C
모든 파일은 연속되어 있어야 합니다. 누락된 연속 파일 이름을 찾고 싶습니다. 이를 위해 별도의 6자리 일련번호를 사용합니다.앗 그리고 사용grep정규식을 사용하여 디렉터리에 파일이 있는지 확인합니다.
`ls|grep "A-B-${sequencenumber}-.*"|wc -l`
그러나 쉘 스크립트는 숫자를 십진수로 처리하지 않으며 다음을 사용하여 숫자를 십진수로 처리하도록 강제하면10#$일련번호그런 다음 파일을 검색하는 데 필요한 앞에 오는 0을 제거합니다.
이 문제를 해결할 방법이 있나요?
답변1
일부 쉘(예: bash)은 산술 표현식에서 앞에 0이 있는 숫자를 8진수로 처리합니다. 이 문제를 해결하는 한 가지 방법은 1000001에서 1999999까지 계산하는 것과 같이 앞에 0이 아닌 추가 숫자가 있는 숫자에만 연산을 수행하는 것입니다. 앞에 0이 있는 원하는 숫자를 얻으려면 문자열 작업을 사용하여 앞에 있는 1을 제거하세요.
n=1000001
while [ "$n" -le 1999999 ]; do
digits=${n#1}
set "A-B-$digits-."*
if [ -e "$1" ] || [ -L "$1" ]; then
echo "${digits}: $#"
fi
n=$((n+1))
done
이 방법은 모든 POSIX 셸에 이식 가능하며 계산을 위한 하위 프로세스를 생성하지 않으므로 속도가 빨라질 수 있습니다(그러나 백만 번의 반복은 어차피 느리고 셸의 성능은 최고가 아닙니다).
위 스크립트에서는 일치하는 파일을 포함 ls
하고 계산하는 wc
복잡하고 느린 명령을 사용하는 대신 쉘 내장 구성을 사용합니다. set "A-B-$digits-."*
위치 인수를 일치하는 파일 목록으로 설정하면 다음 줄은 일치하는 항목 수( $#
)를 인쇄합니다. 일치하는 항목이 하나 이상 있습니다(일치하는 항목이 없으면 패턴은 변경되지 않고 유지되므로 [ -e "$1" ]
false [ -e "A-B-$digits-.*" ]
).
답변2
답변3
wc -l
파일 이름에 개행 문자가 포함된 경우 을 사용하면 올바른 결과가 생성되지 않습니다.
bash
와 함께 zsh
버팀대 확장을 사용할 수 있습니다.
for n in {000001..999999}; do
f=A-B-$n-C
[ -f "$f" ] || printf '%s missing\n' "$f"
done
ksh93
옵션 으로 활성화됨 braceexpand
:
for n in {1..999999%06d}; do
: the code above
done
ksh
및 에서는 zsh
다음을 수행할 수 있습니다.
typeset -Z6 i=1
max=999999
while [ "$i" -le "$max" ]; do
f=A-B-$i-C
[ -f "$f" ] || printf '%s missing\n' "$f"
: "$((i+=1))"
done
POSIX적으로:
min=1
max=999999
while [ "$min" -le "$max" ]; do
f=$(printf "A-B-%0${#max}d-C" "$min")
[ -f "$f" ] || printf '%s missing\n' "$f"
: "$((min+=1))"
done
답변4
awk
나를 위해 작동합니다:
set x=`echo $< | awk '{printf "%d",$1}' ` ; echo $x
033 # this is what I entered
33 # this prints out