부분적인 파일 이름을 기반으로 고유한 파일만 나열

부분적인 파일 이름을 기반으로 고유한 파일만 나열

예를 들어 아래 출력과 같은 파일이 많이 있습니다. 모든 고유 파일 이름 목록을 얻으려고 하지만 "-" 오른쪽에 있는 문자는 무시합니다. 나는 시도 ls -la | grep ....- | sort --unique하고 몇 가지 변형을 시도했지만 필요한 결과를 제공하지 않습니다.

4855-00160880.psi
4855-00160980.ps
4855-00160980.psi
5355-00160880.ps
5355-00160880.psi
5355-00160980.ps
5355-00160980.psi
5855-00160880.ps
5855-00160880.psi
5855-00160980.ps
5855-00160980.psi
5855-00160A80.ps
5855-00160A80.psi

이상적으로는 출력이 다음과 같이 표시되기를 원합니다.

4855
5355
5855

답변1

부터당신은 정말로 분석하고 싶지 않습니다ls, 이렇게 하면 트릭을 수행할 수 있습니다.

find . -type f -maxdepth 1 -exec basename "{}" \; | cut -d'-' -f1 | sort -u

답변2

어때?

printf "%-4.4s\n" ????-* | uniq

쉘은 와일드카드를 알파벳 순서로 확장하고 결과를 인수로 에 전달합니다 printf. 형식 문자열은 각 인수를 4자로 자르고 개행 문자를 추가합니다. 이제 남은 것은 인접한 중복 항목을 제거하는 것입니다.

하이픈 앞의 자릿수를 모르지만 아이디어가 있는 경우 일부 후보를 반복할 수 있습니다.

for expr in '??' '???' '????' '?????'  # Quoted (!)
do
    printf "%-${#expr}.${#expr}\n" $expr-* |  # Unquoted!
    uniq
done

이것은 Bash 전용을 사용합니다매개변수 확장 $[#var}의 문자열 길이를 얻습니다 $var.

루프 초기화에서 확장을 피하기 위해 와일드카드를 인용한 다음 루프 내에서 인용되지 않은 변수를 사용하는 속임수에 주목하세요(대부분의 경우에는 안 됩니다).

답변3

-type f가짜 결과를 피하기 위해 DopeGhoti의 답변에 추가할 가치가 있습니다 ..

find . -maxdepth 1 -exec basename "{}" \; | cut -d'-' -f1 | sort -u
.
4855
5355
5855
find . -maxdepth 1 -type f -exec basename "{}" \; | cut -d'-' -f1 | sort -u
4855
5355
5855
$

원래 시도와 유사하게 유지하려면 이것을 사용할 수 있습니다. ( ls하지만 구문 분석하기 때문에 좋지 않습니다!)

ls -1 | grep ^....-  | cut -c1-4 | sort --unique

awk 기반 솔루션, 여전히 ls를 구문 분석 중

ls -1 | awk -F- '{print $1}' | sort --unique

ls출력이 이미 정렬되어 있으므로 이러한 각 경우에는 실제로 정렬할 필요가 없으므로 uniq.

ls -1 | awk -F- '{print $1}' | uniq

sed 기반 솔루션

ls -1 | sed 's/-.*//' | uniq

ls 구문 분석을 방지하는 find / sed 솔루션

find . -type f -printf "%f\n" | sed 's/-.*//g' | sort --unique

"-" 앞에 항상 4자리 숫자가 있으면 매우 우아합니다.

find . -type f -printf "%.4f\n" | sort -u

답변4

와 함께 zsh:

myfiles=(*-*(.))
print -rl -- ${(u)myfiles[@]%%-*}

이렇게 하면 배열에 대시가 하나 이상 포함된 모든 일반 파일 이름이 저장됩니다. 그런 다음 배열의 각 요소에 대한 매개변수 확장을 사용하여 첫 번째 대시와 그 뒤의 모든 항목을 제거합니다. 중복된 요소는 플래그를 통해 제거됩니다 (u).
숨겨진 파일도 선택하려면 다음을 사용하십시오.myfiles=(*-*(.D))

관련 정보