수백 또는 수천 개의 파일이 있는 폴더가 있고 모두 다음 스키마의 이름을 따서 명명되었다고 가정해 보겠습니다.
<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
이는 모든 이름을 반복합니다. 그런 다음 각 이름에 대해 일치하는 가장 긴 접두사 문자열을 제거합니다 *_
. 그런 다음 접미사가 제거된 나머지 문자열을 출력합니다 .jpg
.
그런 다음 모든 문자열은 마지막에 고유한 문자열 목록만 출력되는 방식으로 정렬됩니다.
디렉토리가 비어 있을 위험이 있는 경우 nullglob
루프( shopt -s nullglob
) 앞에 쉘 옵션을 설정해야 합니다. 이렇게 하면 NET에서 확장되지 않은 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