Если файл является Справочник не перемещает его MV Bash

Это тоже будет работать.

find /var/log -maxdepth 1 -regextype posix-extended -type f ! -regex '^.*/(btmp|wtmp|lastlog)$'
1
24.09.2018, 18:46
3 ответа

Лично я бы использовал цикл 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
2
27.01.2020, 23:15

Я предложу два других метода; один из комментария Кусалананды и один из другой оболочки.

Во-первых, 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будет соответствовать только файлам --, а не каталогам.

2
27.01.2020, 23:15

Вы можете использовать -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
1
27.01.2020, 23:15

Теги

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