다음과 같은 방식으로 하위 디렉터리로 구성된 디렉터리가 있습니다.
a1
b1
c1
c2
c3
d1
주어진 문자의 최신 하위 디렉터리에서만 수행되는 루프를 수행하려고 합니다. 즉 a1
, b1
, c3
, 및 을 반복하지만 합계는 d1
무시합니다 . 지금까지의 노력은 하위 디렉터리 이름의 수치를 직접 비교하는 것에만 집중했는데, 잘 되지 않았습니다. 나는 bash를 처음 접했기 때문에 이것이 내가 놓친 간단한 수정 사항이라면 사과드립니다.c1
c2
답변1
이것은 당신의 목표를 달성한 것 같습니다
#!/bin/bash
for DIR in {a..z}
do
GOOD=$(find ${DIR}[0-9] -type d -print -prune 2>/dev/null | tail -1)
if [[ "$GOOD" ]]; then
echo $GOOD
fi
done
사용 예:
$ mkdir a1 b1 c1 c2 c3 d1
$ ./a.sh
a1
b1
c3
d1
$
답변2
귀하의 작업을 수행하는 약간 복잡한 파이프라인이 있습니다.
#!/bin/bash
find . -maxdepth 1 -type d |
sed -e '/\.$/d' -e '/\.\.$/d' -e 's/\.\/\(.\)\(.\)/\1 \2/' |
sort -k1.1 -k2.1n |
awk 'BEGIN {last=""}
{
if (last == "") {
last = $1; number = $2
} else if ($1 != last) {
printf "%s%s\n", last, number;
last = $1; number = $2
} else {
number = $2
}
}
END { printf "%s%s\n", last, number }
'
find
원하는 결과를 얻으 려면 매개변수를 변경해야 할 수도 있습니다 .
답변3
시리즈의 마지막 요소에 대해 작업하는 한 가지 방법은 이전 항목을 기억하면서 모든 요소를 반복하는 것입니다. 새로운 시리즈가 곧 시작될 것임을 감지하면 기억된 이전 항목에 대해 조치를 취하세요. 테스트되지 않은 코드. 나는 당신이 첫 번째 문자가 점이 아니고 마지막 문자가 숫자인 디렉토리에만 관심이 있다고 가정합니다.
act_on () {
…
}
previous_prefix=0
previous_name=
for x in *[0-9]/; do
x=${x%/}
digits=${x##*[!0-9]}
prefix=${x%"$digits"}
if [ "$prefix" != "$previous_prefix" ] && [ "$previous_prefix" != "0" ]; then
# New prefix, so act on the previous element
act_on "$previous_name"
fi
previous_prefix=$prefix
previous_name=$x
done
act_on "$previous_name"
foo9
이후에 정렬된다는 점에 유의하세요 foo10
. zsh에서 use는 이전에 정렬된 *[0-9](/on)
숫자 정렬을 사용합니다 . zsh를 사용하지 않는 경우 다른 접근 방식을 취해야 합니다. 한 가지 접근 방식은 계열의 첫 번째 항목에 대해서만 연산을 수행하고, 찾은 항목에 대해 연산을 수행하는 대신 접두사를 사용하여 숫자 계열의 마지막 요소를 결정하는 것입니다.9
10
act_on () {
…
}
previous_prefix=0
previous_name=
for x in *[0-9]/; do
x=${x%/}
digits=${x##*[!0-9]}
prefix=${x%"$digits"}
if [ "$prefix" != "$previous_prefix" ]; then
suffixes=
for y in "$prefix"*; do
suffixes="$suffixes
${y#"$prefix"}"
done
last_suffix=$(echo "$suffixes" | sort -n | tail -n 1)
act_on "$prefix$last_suffix"
fi
previous_prefix=$prefix
previous_name=$x
done
답변4
디렉토리 이름이 표시한 것처럼 간단하다면(적어도 공백이나 기타 이상한 내용이 포함되지 않은 경우) 다음을 수행할 수 있습니다.
for d in $(ls | sort -r | rev | uniq -s1 | rev); do echo "$d"; done
이것을 루프가 수행해야 하는 작업으로 echo "$4d"
변경합니다 . 그러나 디렉터리 이름이 표시된 이름과 정확히 일치하지 않으면 모든 오류에 취약하므로 이 작업은 실패합니다.덫ls 구문 분석은 먼저 디렉터리를 나열하고 역순으로 정렬한 다음 역순으로( 가 됨 a1
) 1a
고유한 줄만 유지하고 첫 번째 문자( uniq -s1
)를 무시한 다음 다시 역순으로 복원하여 원래 이름을 복원하는 방식으로 작동합니다.