여러 파일에서 공통점/패턴 찾기

여러 파일에서 공통점/패턴 찾기

다음 스키마로 이름이 지정된 수백 또는 수천 개의 파일이 있는 폴더가 있다고 가정해 보겠습니다.

<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

관련 정보