다음 스키마로 이름이 지정된 수백 또는 수천 개의 파일이 있는 폴더가 있다고 가정해 보겠습니다.
<random number of variable length>_<date code in YYYYMMDD format>.jpg
예:
73923_20180927.jpg
4457582_20180927.jpg
...
18733557_20190401.jpg
23573_20190401.jpg
...
bash 스크립트가 수행할 것으로 기대하는 것은 이러한 날짜 코드 목록을 인쇄하는 것입니다.
20180927
20190401
...
이것은 쉬운 작업처럼 들리지만 실제로는 더 쉬운 작업입니다. 스키마는 항상 동일하므로 파일 이름에서 필요한 부분만 인쇄하기 위해 문자열 작업을 적용하는 방법을 구현했습니다. 그러나 각 날짜를 한 번만 인쇄하는 방법을 여전히 찾고 있습니다.
이 문제를 해결할 영리한 방법이 있나요?
답변1
파일 이름이 모두 패턴과 일치한다고 가정합니다 ./*_*.jpg
.
for name in ./*_*.jpg; do
name=${name##*_} # 4457582_20180927.jpg --> 20180927.jpg
printf '%s\n' "${name%.jpg}" # 20180927.jpg --> 20180927
done | sort -u
이는 모든 이름을 통해 반복됩니다. 각 이름에 대해 일치하는 가장 긴 접두사 string 을 제거합니다 *_
. 그런 다음 접미사가 제거된 나머지 문자열을 출력합니다 .jpg
.
그런 다음 모든 문자열은 마지막에 고유한 문자열 목록만 출력되도록 정렬됩니다.
디렉토리가 비어 있을 위험이 있는 경우 nullglob
루프( ) shopt -s nullglob
이전에 쉘 옵션을 설정해야 합니다 . 이로 인해 확장되지 않은 globbing 패턴을 사용하여 한 번 실행되는 대신 루프가 전혀 실행되지 않습니다 $name
.
특별한 이유 없이 다음과 같이 하면 됩니다 sort
.
declare -A skip=()
for name in ./*_*.jpg; do
key=${name##*_} # 4457582_20180927.jpg --> 20180927.jpg
key=${key%.jpg} # 20180927.jpg --> 20180927
if [[ ! -v skip[$key] ]]; then
printf '%s\n' "$key"
skip[$key]=1
fi
done
여기서는 연관 배열의 키로 출력된 문자열을 추적합니다 skip
. 문자열이 배열의 키에 해당하는 경우 문자열은 출력되지 않습니다.
답변2
실제로 잘못된 파일 이름이 없다고 가정하고 해당 디렉터리에서 실행합니다.
ls -U | awk '-F[_.]' '{ print $2 }' | sort | uniq