Полоса, ведущая точка от имен файлов bash script

У меня есть несколько файлов в кучке каталогов, которые имеют ведущую точку и, следовательно, скрыты. Я хотел бы вернуть это и разбить ведущую точку.

Я не увенчался успехом:

for file in `find files/ -type f`;
do
base=`basename $file`
if [ `$base | cut -c1-2` = "." ];
then newname=`$base | cut -c2-`;
dirs=`dirname $file`;
echo $dirs/$newname;
fi
done

Что не выполняется при выполнении условия:

[: =: unary operator expected

Кроме того, некоторые файлы имеют в них пробел, и файл возвращает их split.

Любая помощь будет оценена.

Ответ 1

Самый простой способ удалить что-либо из начала переменной - это использовать ${var#pattern}.

$ FILENAME=.bashrc;    echo "${FILENAME#.}"
bashrc
$ FILENAME=/etc/fstab; echo "${FILENAME#.}"
/etc/fstab

См. справочную страницу bash:

${параметр # слово}
${параметр ## слово}

Слово расширяется для создания шаблона так же, как при расширении пути. Если шаблон совпадает с началом значения параметра, то результатом расширения является               расширенное значение параметра с кратчайшим шаблоном соответствия ( "случай #" ) или самый длинный шаблон соответствия ( "случай ##" ).

Кстати, с более избирательной командой find вам не нужно выполнять всю тяжелую работу. Вы можете иметь find только совпадающие файлы с ведущей точкой:

find files/ -type f -name '.*'

Бросьте все вместе, затем:

find files/ -type f -name '.*' -printf '%P\0' |
    while read -d $'\0' path; do
        dir=$(dirname "$path")
        file=$(basename "$path")
        mv "$dir/$file" "$dir/${file#.}"
    done

Дополнительные примечания:

  • Чтобы правильно обрабатывать имена файлов с пробелами, вам нужно указывать имена переменных, когда вы ссылаетесь на них. Напишите "$ file" вместо просто $file.

  • Для дополнительной надежности -printf '\0' и read -d $'\0' используют символы NUL в качестве разделителей, поэтому будут работать даже имена файлов со встроенными новыми строками '\n'.

Ответ 2

find files/ -name '.*' -printf '%f\n'|while read f; do
        mv "files/$f" "files/${f#.}"
done

Ответ 3

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

* Примечание: я включил echo, чтобы вы могли протестировать его как сухой. Удалите одиночный echo, если вы удовлетворены результатами.

find . -name '.*' -exec sh -c 'for arg; do d="${arg%/*}"; f=${arg:${#d}}; echo mv "$arg" "$d/${f#.}"; done' _ {} +