С awk
установка разделителя полей и разделителей записей к варианту использования:
awk 'BEGIN { FS="\n"; RS ="" } /testvar/' yourfile
testvar=test1 \
test2 \
test3
Посмотрите ручную запись для нескольких записей строки.
Вы можете использовать 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
никогда не бывает хорошей идеей - просто не пытайтесь.)
Вы используете 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
для поиска только в текущем каталоге, если нужно рекурсивное, удалите его.
Не нужно усложнять! Почему бы просто не:
mkdir../temp
mv *.{jpg,png,gif,xcf}../temp/
mv * /desired/target/directory/
mv../temp/*.
rmdir../temp
Конечно, это не будет работать для всего дерева каталогов, только для одного плоского каталога с файлами.