Это тоже будет работать.
find /var/log -maxdepth 1 -regextype posix-extended -type f ! -regex '^.*/(btmp|wtmp|lastlog)$'
Лично я бы использовал цикл find
и while
, так как вы можете указать тип файла с помощью -type d/f
для каталога/файла соответственно
как "один вкладыш" из каталога, из которого вы будете запускать:
find. -maxdepth 1 -type f -name "*.*" | while IFS="" read -r line; do filename=$(basename -- "$line"); extension="${filename##.}.files"; mkdir -p "$extension"; mv "$line" "$extension"; done
Или в сценарии:
#!/bin/bash
find. -maxdepth 1 -type f -name "*.*" |
while IFS="" read -r line; do
filename=$(basename -- "$line")
extension="${filename##.}.files"
mkdir -p "$extension"
mv "$line" "$extension"
done
find.
-находит файлы и каталоги из текущего каталога
-maxdepth 1
-проверяет только текущий каталог (2 также проверяет каталоги следующего уровня)
-type f
-соответствует только файлам
-name *.*
-любой файл с "." во имя
Я также изменил расширение на .files
в одном объявлении переменной, поскольку я предполагаю, что это то, что вам нужно. Если вы хотите, чтобы tmp.txt
находилась в каталоге с именем tmp.txtfiles
вместо (, как в вашем сценарии в настоящее время ), просто удалите "." вот так:
extension="${filename##.}files"
Итак, как указал @Kusalananda, зацикливание на find
может быть плохой идеей. При этом вы все еще можете использовать find
для этого, просто используя вместо этого временный файл для зацикливания:
#!/bin/bash
find. -maxdepth 1 -type f -name "*.*" > myTemporaryFile
IFS=$'\n' # in case any filenames have spaces in them
for line in $(cat myTemporaryFile); do
filename=$(basename -- "$line")
extension="${filename##.}.files"
mkdir -p "$extension"
mv "$line" "$extension"
done
rm myTemporaryFile
Я предложу два других метода; один из комментария Кусалананды и один из другой оболочки.
Во-первых, bash (и другие оболочки )имеют простой test
оператор для проверки того, является ли что-то каталогом:[ -d something ]
; вы могли бы использовать это так:
#!/bin/bash
for i in *.*; do
[ -d "$i" ] && continue
#... rest of the script
done
В приведенном выше примере каждый «файл» из подстановочного знака *.*
проверяется, является ли он каталогом; если это так, тест пройден, и цикл продолжается со следующего элемента (, если он есть ).
В качестве альтернативы вы можете использовать zsh, который имеет обширные функции подстановочных знаков, одна из которых заключается в ограничении совпадений с определенными типами файлов (обычными файлами, каталогами и т. д. ). Вы можете использовать его как:
#!/bin/zsh
for i in *.*(.)
do
#... rest of your script
done
Специальный синтаксис (.)
— это "квалификатор glob" ; скобки указывают, что это квалификатор, а точка говорит, что мы ищем простые файлы. В результате цикл for
будет соответствовать только файлам --, а не каталогам.
Вы можете использовать -f
в операторе if
, чтобы проверить, является ли это файлом:
if [ -f "${i}" ];then
echo "${i} is a file."
else
echo "${i} is not a file."
fi
-d
можно использовать, чтобы определить, является ли это каталогом, а !
можно использовать с префиксом, чтобы инвертировать логику, т. е. проверить, не является ли переменная файлом:
if [ ! -f "${i}" ];then
echo "${i} is not a file"
fi