Bash копирует все файлы, которые не соответствуют данным расширениям

С awk установка разделителя полей и разделителей записей к варианту использования:

awk 'BEGIN { FS="\n"; RS ="" } /testvar/' yourfile
testvar=test1 \
        test2 \
        test3

Посмотрите ручную запись для нескольких записей строки.

7
05.08.2014, 01:48
3 ответа

Вы можете использовать find , чтобы найти все файлы в дереве каталогов, которые соответствуют (или не соответствуют) некоторым конкретным тестам, а затем что-то с ними сделать. Для этой конкретной проблемы вы можете использовать:

find -type f ! \( -iname '*.png' -o -iname '*.gif' -o -iname '*.jpg' -o -iname '*.xcf' \) -exec echo mv {} /new/path \;

Это ограничивает поиск обычными файлами ( -тип f ), а затем файлами, имена которых не имеют (! ) расширение *. png в любом регистре ( -iname '* .png' ) или ( -o ) *. gif , и скоро. Все расширения сгруппированы в одно условие между \ (... \) . Для каждого совпадающего файла он запускает команду ( -exec ), которая перемещает файл, имя которого вставлено вместо {} , в каталог / new / путь . \; сообщает find , что команда завершена.

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


Если вы хотите сделать это прямо внутри Bash, вы можете использовать расширенные возможности Bash сопоставления с образцом . Для этого необходимо, чтобы shopt extglob был включен, а также globstar . В этом случае используйте:

mv **/!(*.[gG][iI][fF]|*.[pP][nN][gG]|*.[xX][cC][fF]|*.[jJ][pP][gG]) /new/path

Это соответствует всем файлам в подкаталогах ( ** ), которые не соответствуют *. Gif , *. Png и т. Д. , в любой комбинации наборов символов и перемещает их на новый путь. Расширение выполняется оболочкой, поэтому пробелы и специальные символы снова не имеют значения.

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

Подобные функции есть в zsh и других оболочках, но вы указали, что используете Bash.


(Еще одно примечание: синтаксический анализ ls никогда не бывает хорошей идеей - просто не пытайтесь.)

12
27.01.2020, 20:15

Вы используете Ubuntu, так что GNU найдет, попробуйте:

find . -maxdepth 1 ! -iregex ".*\.\(jpg\|png\|gif\|xcf\)$" -exec mv -- -t /path/to/newdir "{}" +
  • -iregex использовать regex для поиска имени файла, но без учета регистра, ! отрицает регекс. Команда

  • -exec + выполнит команду для поиска файлов, соответствующих друг другу. Это похоже на использование find -print0 с xargs -0. Используя это, мы можем переместить несколько найденных файлов с помощью одной команды mv, так что общее количество команд вызова меньше, чем количество совпадающих файлов.

  • -maxdepth 1 предел find для поиска только в текущем каталоге, если нужно рекурсивное, удалите его.

2
27.01.2020, 20:15

Не нужно усложнять! Почему бы просто не:

mkdir../temp
mv  *.{jpg,png,gif,xcf}../temp/
mv * /desired/target/directory/
mv../temp/*.
rmdir../temp

Конечно, это не будет работать для всего дерева каталогов, только для одного плоского каталога с файлами.

0
27.01.2020, 20:15

Теги

Похожие вопросы