Вопрос поиск и удаление условного файла


У меня есть некоторые элементы, которые имеют 15 изображений, а некоторые из них имеют менее 15 изображений, связанных с их идентификаторами. Как я могу сохранить только те, у которых есть 15 изображений?

$ ls -l 72065050* | wc -l
15
$ ls -l 71088714* | wc -l
3

а также

$ ls 71088714*
71088714_0.jpg  71088714_1.jpg  71088714_2.jpg
$ ls 72065050*
72065050_0.jpg   72065050_11.jpg  72065050_13.jpg  72065050_1.jpg  72065050_3.jpg  72065050_5.jpg  72065050_7.jpg  72065050_9.jpg
72065050_10.jpg  72065050_12.jpg  72065050_14.jpg  72065050_2.jpg  72065050_4.jpg  72065050_6.jpg  72065050_8.jpg

Кроме того, как я могу определить, сколько из этих идентификаторов имеет 15 изображений, связанных с ними?


1
2017-11-20 19:13


происхождения




ответы:


Непроверенный, но вы можете сделать что-то вроде:

printf "%s\n" *.jpg | cut -d_ -f1 | sort -u | while IFS= read -r prefix; do
    files=( "$prefix"*.jpg )
    if [[ "${#files[@]}" -ne 15 ]]; then
        echo rm "$prefix"*
    fi
done

Это находит список уникальных префиксов и, для каждого, помещает список файлов в массив: если размер массива не равен 15, тогда удалите.


3
2017-11-20 19:39



Вы имеете в виду «если размер массива не 15 затем удалите. ", Не так ли? Вы должны упомянуть, что echo необходимо удалить после тестирования, это может быть неочевидным для всех. - dessert
это также не удаляло файлы. Он просто перекликается с тем, что он удаляет файлы. - Mona Jalal
@Mona предположительно, что вы можете безопасно протестировать скрипт, не удаляя ваши файлы, вы просто удаляете echo как только вы протестировали скрипт и увидите, что он работает - Olorin
Мудрое примечание. Спасибо за объяснение - Mona Jalal
@MonaJalal * должно быть, вне кавычек, я исправил это сейчас. @ glen - возможно, вы можете использовать uniq -c и сделать подсчет бесплатным? Прямо сейчас вы трижды забиваете - один раз для printf, один раз для подсчета, один раз для удаления. По крайней мере один из них может быть устранен - muru


#!/bin/bash
find . -maxdepth 1 -iname '*.jpg' |\
while IFS='' read -r bla; do
  if ! ls "${bla:0:7}"_14.jpg >/dev/null 2>&1; then
    echo rm "${bla:0:7}"*
  fi
done

1
2017-11-20 19:34



от канала #linux IRC! Благодаря! - Mona Jalal
Вместо того, чтобы полагаться на ls, вы можете попросить оболочку посмотреть, существует ли этот файл: if [[ ! -f "${bla:0:7}_14.jpg" ]]; then ... - glenn jackman
>/dev/null 2>&1 равняется &>/dev/nullв современном bash, - dessert
Вы должны упомянуть, что echo необходимо удалить после тестирования, чтобы выполнить удаление. - dessert
эй, я просто понял, что это не удаление файлов, а только эхо, которое удаляется, но это не так. Как это исправить? - Mona Jalal


Другой возможный ответ:

$ declare -A pref ; for f in *_[0-9]*.jpg ; do p=${f%_*} ; (( pref[$p]++ )); done ; for p in "${!pref[@]}" ; do (( ${pref[$p]} < 15 )) &&  rm "$p"_* ; done

0
2017-11-21 00:20





Вы также можете использовать язык без оболочки для этой задачи:

ruby -e '
  files = Dir.glob("*")
  groups = files.group_by {|f| f.sub(/_.*/, "")}
  groups.each_value {|flist| File.delete(*flist) if flist.length < 15}
'

или

perl -e '
    foreach $f (glob "*") {
        ($prefix = $f) =~ s/_.*//;
        push @{$groups{$prefix}}, $f;
    }
    foreach $flist (values %groups) {
        unlink @$flist if (scalar @$flist < 15);
    }
'

0
2017-11-21 15:06