невозможно обработать файлы каталога для цикла в Linux - PullRequest
0 голосов
/ 09 июня 2011

У меня есть каталог, в котором есть 2 подкаталога, и в котором также есть несколько подкаталогов, и у них есть несколько файлов.Мне нужно переименовать все файлы, чтобы добавить расширение HTML к именам файлов.структура каталогов выглядит следующим образом

main-directory
   sub-directory
   sub-directory
       sub-directory
          file1
          file2
          and so on to lot of files

Теперь я не могу использовать что-то вроде этого

for file in main-directory/*
do
if [ -f "$file" ]
then `mv "$file" "$file.html"`
fi
done

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

for file in `ls -1R main-directory`  // -1 for showing file and directory names separated by new lines and -R for recursive travel
do
if [ -f "$file" ]
then `mv "$file" "$file.html"`
fi
done

вышеупомянутый код не может переименовывать файлы.чтобы проверить, работает ли строка

for file in `ls -1R main-directory`  

, я написал что-то вроде этого

for file in `ls -1R main-directory`
do
if [ -f "$file" ]
echo $file
done

это ничего не показывает.что может быть не так?

Ответы [ 4 ]

3 голосов
/ 09 июня 2011

вы можете использовать поиск и просмотр файла типа, а затем -exec, чтобы изменить весь файл, а затем добавить .html.

find main-directory -type f -exec mv -v '{}' '{}'.html \; 
1 голос
/ 09 июня 2011

В вашем первом цикле for команда mv не должна быть в обратном тике.

Во втором цикле for оператор if имеет неверный синтаксис. Нет then или fi. Должно быть:

for file in `ls -1R main-directory`
do
if [ -f "$file" ]
then
   echo $file
fi
done

Но даже тогда это не сработает, потому что ls -1R main-directory дает вам только имена файлов, а не абсолютные пути к файлу. Переместите свое эхо за пределы оператора if для проверки:

for file in `ls -1R main-directory`
do
   echo $file
done

Поэтому ls -1R main-directory не является хорошим способом получить все файлы в текущем каталоге. Вместо этого используйте find . -type f.

0 голосов
/ 09 июня 2011

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

IFS=$'\n'   // this is for setting field separator to new line because the default is whitespace
dir=main-directory
for file in `ls -1R main-directory | sed 's/:$//'`  // -1 for showing file and directory names separated by new lines and -R for recursive travel
do
if [ -f "$dir/$file" ]
then `mv "$dir/$file" "$dir/$file.html"`
elif [ -d "$file" ]
then dir=$file
fi
done

здесь sed 's/:$//' обнаруживает : в конце строки и удаляет его. это было одной из причин, мешавших запуску моего кода, потому что всякий раз, когда ls -1R main-directory обнаруживал каталог, к нему добавлялся : в конце

0 голосов
/ 09 июня 2011

По какой-то причине я никогда не могу вспомнить синтаксис find ... -exec на макушке с {} и \;. Вместо этого у меня появилась привычка просто использовать цикл, получаемый из find:

find main-directory -type f | while read file
do
    mv "$file" "$file.html"
done

find выводит каждый файл на стандартный вывод, а read file будет использовать по одной строке за раз и устанавливает содержимое этой строки в переменную окружения $file. Затем вы можете использовать это в любом месте тела вашего цикла.

Я использую этот подход для решения множества небольших проблем, таких как эта, где мне нужно перебрать кучу выходных данных и сделать что-то полезное. Поскольку он более универсален, я использую его больше, чем эзотерический подход find ... -exec {} \;.

Еще одна хитрость заключается в добавлении команды к echo для быстрой проверки работоспособности перед тем, как нанести вред вашей системе:

find find main-directory -type f | while read file
do
    echo mv "$file" "$file.html"
done
...