Переместить группу файлов, запрашивая у пользователя подтверждение для каждого файла

9

Система: Ubuntu MATE 18.04.

У меня есть коллекция файлов (в нескольких каталогах в структуре каталогов), и я хочу переместить многие из них в другой каталог. Я могу сказать, какие файлы я хочу переместить, по их именам (они являются названиями рецептов), но нет другого способа отличить файлы, которые я хочу переместить, и файлы, которые я не хочу переместить; Мне нужно принять решение по каждому файлу, проверяя имя самостоятельно.

Итак, я запускаю команду один раз для каждого файла, который я хочу переместить, как

mv Snacks/OkaraCrackers NeedsTesting/
mv Snacks/SunflowerBrittle NeedsTesting/
mv Treats/ChocolateChilliFudge NeedsTesting/
mv Treats/PecanBlondies NeedsTesting/

Даже с завершением табуляции это слишком много печатать. Что я действительно хочу сделать, это что-то вроде

shopt -s globstar
mv --prompt-me-for-every-file ** NeedsTesting/

Так что я могу просто нажать yили nдля каждого файла.

Как я могу переместить группу файлов и получить подтверждение для каждого файла?

Занна
источник

Ответы:

6

Способ 1: в графическом браузере файлов, используя древовидное представление

Я предполагаю, что ваша реальная цель - сделать выбор для каждого файла, а не строго говоря, чтобы его попросили . Однако, если вы предпочитаете получать подсказки о каждом файле в терминале, см. Способ 2 ниже.

Большинство графических файловых браузеров поддерживают древовидное представление, где вы можете просматривать несколько уровней иерархии каталогов вместе. Вы можете копировать или перемещать файлы из этого представления либо по отдельности, либо выделив их, а затем воздействуя на весь выбор. Это работает даже с файлами из нескольких папок.

В некоторых файловых браузерах нужно войти в меню настроек, чтобы включить древовидное представление. В Caja, файловом браузере MATE, он всегда включен в виде списка. Нажмите Вид → Список (или нажмите Ctrl+ 2), чтобы переключиться на вид списка. Каждый каталог имеет небольшой направленный вправо треугольник слева от него, указывая, что его можно развернуть. Чтобы развернуть папку, щелкните этот треугольник или нажмите клавишу (стрелка вправо), когда папка выбрана. В этом примере я выбрал их всех один за другим и перетаскиваю их всех сразу к месту назначения:

несколько файлов, выбранных в древовидной структуре в браузере файлов Caja, перетаскиваемых в другую папку, но еще не перемещенных

Предполагая, что источник и пункт назначения находятся на одном диске, перетаскивание перемещается по умолчанию. Если вы хотите скопировать вместо этого, вы бы удерживали Ctrlклавишу.

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

Теоретически, при использовании этого метода легко исправить ошибки, потому что большинство файловых браузеров (включая Caja) поддерживают Ctrl+ Zдля отмены недавних действий, включая пакетные действия. Однако мне повезло с этим. Иногда файлы возвращаются в неправильную папку.

Хорошей новостью является то, что вы, похоже, работаете в основном с текстовыми документами, которые имеют тенденцию быть маленькими, поэтому вы можете сделать дополнительную резервную копию с tarпервой без особых хлопот. Я предлагаю делать это независимо от того, какой метод вы используете.

Способ 2 : findкоманда с -okдействием

Это обычное использование , findчтобы найти файлы и передавать их пути к произвольной внешней команде с -execи -execdirдействиями. Но findтакже есть -okи -okdirто, что подсказывают перед каждым запуском команды. Если вы действительно хотите, чтобы в терминале вас спрашивали о каждом файле, я думаю, что это путь.

Когда сделано, чтобы произвести те же эффекты, как показано выше, это выглядит так:

ek@Gnar:~$ find Texts -xtype f -ok mv -t 'Glorious Destination Folder' {} \;
< mv ... Texts/Robert Frost/New Hampshire.pdf > ? y
< mv ... Texts/Robert Frost/In The Clearing.pdf > ? n
< mv ... Texts/Helen Keller/The Story of My Life.pdf > ? y
< mv ... Texts/Saki/The Short Stories of Saki.pdf > ? y
< mv ... Texts/Jane Austen/Sense and Sensibility.pdf > ? n
< mv ... Texts/Jane Austen/Pride and Prejudice.pdf > ? y
< mv ... Texts/Richard Connell/The Stolen Crime.pdf > ? n
< mv ... Texts/Richard Connell/The Most Dangerous Game.txt > ? y
< mv ... Texts/Mary Wollstonecraft Shelley/Mathilda.epub > ? n
< mv ... Texts/Mary Wollstonecraft Shelley/Frankenstein: Or, The Modern Prometheus.pdf > ? y
< mv ... Texts/W. E. B. Du Bois/The Souls of Black Folk.pdf > ? n
< mv ... Texts/W. E. B. Du Bois/Darkwater: Voices from within the Veil.htm > ? y

Замените Textsна исходный каталог (который может быть просто, .если вы cdк нему) и Glorious Destination Folderреальный каталог назначения.

Это запускает одну команду на файл; в отличие от -execи -execdir, -okи -okdirне поддерживают +вместо того, \;чтобы передавать несколько найденных путей в одном и том же вызове команды. Следовательно, вам не нужно использовать -t destформу mv. Я предлагаю делать это в любом случае, хотя, как в целом с findи особенно в этой ситуации , так что подсказки выглядят как команды они побудившие о.

Когда эта команда написана, если findвстречается символическая ссылка, которая в конечном итоге указывает на обычный файл, она (ссылка, а не цель) перемещается, а не игнорируется. Если вы действительно хотите работать только с одним обычным файлом, используйте -type fвместо -xtype f.

Возможно, вы захотите сделать это во время scriptсеанса, чтобы вы могли выяснить, что произошло, если вы допустили ошибку. Но опять же, нет причин не иметь резервную копию.

Способ 3: создать манифест и отредактировать его

По крайней мере, до тех пор, пока файлы не имеют новых строк в своих именах, вы можете начать с использования простой findкоманды для генерации манифеста - файла, в котором перечислены имена файлов, которые вас (в данном случае потенциально) интересуют :

find Texts -xtype f >manifest

Замените manifestна любое имя, которое вам нравится, для файла, в котором перечислены рассматриваемые файлы (и соответственно измените оставшиеся направления).

Как и выше, замените его Textsсвоим действительным исходным каталогом, который мог бы быть, .если бы вы cdк нему обратились. Однако, если Textsэто относительный путь (в том числе, если он есть .), то вы должны быть уверены, что будете в том же месте позже, когда будете выполнять ходы.

После выполнения этой findкоманды откройте manifestв текстовом редакторе. Это может быть nano, vim, emacs, gedit, plumaи т.д. В редакторе закомментируйте линий, название файлов , которые вы не хотите , чтобы двигаться, поставив #в начале их. Некоторые редакторы выделяют эти строки по-разному, даже если они не распознают ваш файл в любом формате, который, как он знает, имеет комментарии. Однако большинство этого не сделает, и реальная причина, по которой я предлагаю сделать это, состоит в том, что вы, как человек, скорее всего, будете иметь опыт комментирования строк в файлах конфигурации (и, возможно, в исходном коде). Я думаю, что это более интуитивно понятно и менее подвержено ошибкам, чем это было бы для обозначения линий, которые вы хотите переместить.

Конечно, вместо этого вы можете просто удалить строки для файлов, которые вы не хотите перемещать. Преимущество их комментирования в том, что позже станет ясно, что вы сделали.

В моем примере это то, как выглядело содержимое файла после того, как я его отредактировал:

Texts/Robert Frost/New Hampshire.pdf
# Texts/Robert Frost/In The Clearing.pdf
Texts/Helen Keller/The Story of My Life.pdf
Texts/Saki/The Short Stories of Saki.pdf
# Texts/Jane Austen/Sense and Sensibility.pdf
Texts/Jane Austen/Pride and Prejudice.pdf
# Texts/Richard Connell/The Stolen Crime.pdf
Texts/Richard Connell/The Most Dangerous Game.txt
# Texts/Mary Wollstonecraft Shelley/Mathilda.epub
Texts/Mary Wollstonecraft Shelley/Frankenstein: Or, The Modern Prometheus.pdf
# Texts/W. E. B. Du Bois/The Souls of Black Folk.pdf
Texts/W. E. B. Du Bois/Darkwater: Voices from within the Veil.htm

Затем вы можете отфильтровать закомментированные строки с помощью grepи xargsпередать результат, чтобы передать их mv:

grep -Pv '^\s*#' manifest | xargs -d '\n' mv -t 'Glorious Destination Folder'

Как указано выше, замените Glorious Destination Folderимя фактического пункта назначения. Это оно; ваши файлы перемещены. Конечно, вы можете написать echoраньше, mvчтобы увидеть команды, которые будут выполняться первыми, если хотите.

Эта команда работает так:

  1. Команда grepвыводит строки из manifestэтого not ( -v) start ( ^) с необязательным *пробелом ( \s), за которым следует буквальный #символ. -PФлаг выбрать PCRE как диалект регулярных выражений (что позволяет , \sкоторые я считаю более удобным для чтения , чем традиционный [[:space:]]).
  2. Команда xargsделит свои входные данные (которые являются выходными grepданными) на завершенные символом новой строки поля ( -d '\n'), а затем вставляет каждое поле (без завершающего символа новой строки) в качестве отдельного аргумента в конце команды mv -t 'Glorious Destination Folder', которую она выполняет.
Элия ​​Каган
источник
1
-okИМХО лучший ответ
ПИМ
7

Вот небольшой скрипт ( mv-confirm.sh):

#!/bin/bash

# Just make sure there are at least one source and one destination
if [ "$#" -lt 2 ]; then
    echo "Illegal number of parameters"
fi

DESTINATION=${*:$#}             # last argument
SOURCES=( ${@:1:$#-1} )         # all but last arguments

for i in "${SOURCES[@]}"
do
    read -p "move '$i' to '$DESTINATION' ? [y/n] " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]
    then
        echo mv "$i" "$DESTINATION"
    fi
done

Образец использования:

./mv-confirm.sh ** somewhere
move 'a' to 'somewhere' ? [y/n] n
move 'b' to 'somewhere' ? [y/n] y
mv b d
...

не забудьте сделать скрипт исполняемым ( chmod +x mv-confirm.sh).

NB

Поскольку я не хочу связываться с вашими файлами, я добавил echoперед фактической mv командой. Не стесняйтесь удалить его для фактического перемещения файлов.

ПИМ
источник