Выводить список уникальных файлов только на основе частичного имени файла

Выводить список уникальных файлов только на основе частичного имени файла

Например, у меня есть много файлов, которые выглядят как вывод ниже, я пытаюсь получить список всех уникальных имен файлов, но игнорирую символы справа от "-". Я пробовал 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. Строка формата обрезает каждый аргумент до четырех символов и добавляет новую строку. Теперь остается только удалить смежные дубликаты.

Если вы не знаете количество цифр перед дефисом, но у вас есть идея, вы можете перебрать несколько кандидатов:

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

найти / sed решение, которое избегает разбора ls

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))

Связанный контент