Переименование серии файлов - PullRequest
2 голосов
/ 06 мая 2009

Попытка переименовать серию файлов на сервере Linux. Найти нужные файлы легко:

find . -type f -wholename \*.mbox

Конечно, будучи файлами mbox, некоторые из них имеют пробелы в именах, поэтому он становится:

find . -type f -wholename \*.mbox -print0

Я пишу в xargs, чтобы переименовать файлы:

find . -type f -wholename \*.mbox -print0 | xargs -0 -I{} echo ${"{}"/.mbox/}

Эхо должно возвращать что-то вроде INBOX, учитывая INBOX.mbox, однако, bash жалуется:

bash: ${"{}"/.mbox/}: bad substitution

Как я могу это исправить? Я хотел бы попытаться сохранить его в решении find / xargs, если это возможно, чтобы не добавлять вокруг него много циклических конструкций.

Ответы [ 6 ]

8 голосов
/ 06 мая 2009

Попробуйте

find . -type f -wholename \*.mbox | sed 's/\(.*\)\.mbox/mv "\1.mbox" "\1"/' | sh

Это не является 100% доказательством того, что некоторые файлы содержат символы двойной кавычки, но я полагаю, что вы можете игнорировать это:)

2 голосов
/ 10 июня 2010

GNU Parallel http://www.gnu.org/software/parallel/ имеет {.}, Который удаляет расширение:

find . -type f -wholename \*.mbox -print0 | parallel -0 mv {} {.}

Если вы знаете, что имена файлов не содержат \ n, это также будет работать:

find . -type f -wholename \*.mbox | parallel mv {} {.}
1 голос
/ 06 мая 2009

Не могли бы вы использовать переименование (1)? Поставляется с Perl.

1 голос
/ 06 мая 2009

Я думаю, вам нужно это:

find . -wholename \*.mbox | awk '{new=$0; gsub("\.mbox$", "", new) ; system("mv \"" $0 "\" \"" new "\"") }'

(должно быть совместимо с gawk и mawk, протестировано на mawk). Он не использует xargs, но учтите, что он не создает новый процесс для каждого перемещенного файла. Если вам нужно переместить большое количество файлов, вы заметите преимущество. Предупреждение: если какой-либо из файлов будет содержать новую строку в названии, у вас будут проблемы (но если это проблема, Бог с вами).

Для дальнейшего улучшения этого решения вы можете использовать xargs для удаления нескольких файлов за один rm вызов.

Если вам действительно нужна скорость, я бы посоветовал вам использовать скрипт на python вместо awk. Это сделает все rm без единой вилки.

1 голос
/ 06 мая 2009

Вы можете попробовать:

find . -type f -wholename \*.mbox -print0 | sed 's/\.mbox//'

Ваша проблема в том, чтобы попытаться отправить в xargs. К этому моменту "{}" ничего не значит.

Чтобы переименовать файлы (при условии, что вы находитесь под Bash)

find . -type f -wholename \*.mbox -print0 | \
    while read I ; do
        mv $I $(echo $I | sed 's/\.mbox//') ;
    done ;
0 голосов
/ 02 марта 2010

Вот, пожалуйста, это должно сработать ....

# find .
.
./test.tst
./test1.tst
./test2.tst
./test/test4.tst
./test/test5.tst

#

for file in `find . -type f`
do
mv $file ${file%.tst}.new
done

# find .
.
./test
./test/test4.new
./test/test5.new
./test1.new
./test2.new
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...