2014-11-15 4 views
1

я сначала создать 10 цифр случайное числоКак переименовать все файлы в каталоге, добавив префикс

export mask=$RANDOM$RANDOM$RANDOM; let "mask %= 10000000000"; 

Эта команда работает хорошо

for i in /home/testing/*; do mv "$i" "$mask$i"; done 

Проблема с приведенной выше команды является то, что это только работает когда я нахожусь в/home/testing. Как только я переведу сценарий, я получаю эту ошибку

mv: cannot move ‘/home/testing/rec001.mp4’ to ‘3960731225/home/testing/rec001.mp4’: No such file or directory 

Что я здесь делаю неправильно?

+0

Почему эта помеченная MySQL ?! – Alnitak

+0

Кроме того, в первой версии ваш '$ i' должен по-прежнему быть абсолютным путем, поэтому нет причин, почему текущая рабочая директория должна иметь значение. Это будет иметь значение только в том случае, если ваша первая версия говорит 'for i in *; ... ' – Alnitak

+0

Тогда почему ошибка msg? – Andy

ответ

1

Вы должны отделить path от filenameдо того вы применяете mask. Например, чтобы использовать в сценарии, где каталог передается в качестве аргумента сценария:

path="$1" 

## Note: this assumes you are exporting mask earlier. If not, set mask here 

for i in "${path}"/*; do 

    dir="${i%/*}"  # path component 
    ffname="${i##*/}" # filename component 

    mv "$i" "${dir}/${mask}${ffname}" 

done 

Это будет применяться mask ко всем файлам в данном каталоге, независимо от того, где этот каталог.

Пример сценария, который включает в себя это, показан ниже. Вы можете сохранить этот сценарий там, где хотите. Вы можете сделать его исполняемым chmod 0755 scriptname или позвонить по телефону bash scriptname. Чтобы использовать сценарий, добавьте путь, по которому вы хотите префикс файлов, в качестве первого аргумента . Например bash scriptname /path/to/files (или просто scriptname /path/to/files, если вы сделали это исполняемый файл):

#!/bin/bash 

# validate input 
[ -n "$1" ] || { 
    printf "error: insufficient input. Usage: %s /path/to/files\n" "${0//\//}" 
    exit 1 
} 

# validate directory 
[ -d "$1" ] || { 
    printf "error: directory not found: '%s'\n" "$1" 
    exit 1 
} 

path="$1" 

## Note: this assumes you are exporting mask earlier. If not, set mask here 

## validate mask set and is 10 chars (added per comment) 
[ -n "$mask" -a "${#mask}" -eq 10 ] || { 
    printf "error: mask '%s' either unset or not 10 characters\n" "$mask" 
    exit 1 
} 

# move files 
for i in "${path}"/*; do 

    [ -f "$i" ] || continue # if not file, skip 

    dir="${i%/*}"   # path component 
    ffname="${i##*/}"  # full filename component (with .ext) 

    mv "$i" "${dir}/${mask}${ffname}" 

done 

Вот пример того, что движется будет происходить со сценарием под названием prefix.sh при вызове на каталог dat в текущем рабочем каталоге и при вызове по ~/tmp за пределами текущего каталога:

выходной (маска = 3960731225):

$ ./prefix.sh dat 

dat/f1f2.dat => dat/3960731225f1f2.dat 
dat/field.txt => dat/3960731225field.txt 
dat/flop.txt => dat/3960731225flop.txt 
dat/hh.dat  => dat/3960731225hh.dat 
dat/hh1.dat => dat/3960731225hh1.dat 
dat/hostnm  => dat/3960731225hostnm 
dat/hosts.dat => dat/3960731225hosts.dat 

$ ./prefix.sh ~/tmp 

    /home/david/tmp/tcpd.tar.xz  => /home/david/tmp/3960731225tcpd.tar.xz 
    /home/david/tmp/tcpdump-capt  => /home/david/tmp/3960731225tcpdump-capt 
    /home/david/tmp/tcpdump.new.1000 => /home/david/tmp/3960731225tcpdump.new.1000 
    /home/david/tmp/test    => /home/david/tmp/3960731225test 
+0

Немного потеряно.Как мне сказать, переименовать/home/testing/*, если мой скрипт находится в/home? – Andy

+0

Извините, вам нужно каким-то образом передать путь к циклу. Вы можете либо жестко закодировать его (не очень полезно), либо передать путь в качестве аргумента скрипту. Затем вы вызываете 'script/path/to/files/to/mv' (обратите внимание на отсутствие конца'/'). Я напишу полный пример. –

+0

Кажется, что это хорошо работает, но по какой-то причине маска, иногда это всего лишь 9 цифр, а затем она заполняет все мои файлы. Есть ли подсказки, почему это произойдет? – Andy

0

Как о добавлении команды cd перед вашей командой сейчас, куда вы хотите переместить сценарий он работает,

cd /home/testing 

for i in /home/testing/*; do mv "$i" "$mask$i"; done 
+0

@ Энди проверить мой ответ, я уверен, проблема будет решена. – Skynet

+0

Спасибо, но не работает. он делает $ i путь как filename – Andy

1

Существует две команды, которые весьма полезно, имя файла и имя-каталога. Они передадут вам часть каталога и имя файла, посмотрите на этот тестовый скрипт.

#!/bin/bash 

mask=$RANDOM$RANDOM$RANDOM; let "mask %= 10000000000"; 
echo $mask 

mkdir -p testing 
> testing/nisse.txt 
> testing/guste.txt 
> testing/berra.txt 

ls testing/ 

for i in testing/* 
do 
    file=$(basename $i) 
    dir=$(dirname $i) 
    newfile=$mask$file 
    echo $i $dir $file $newfile 

    mv "$dir/$file" "$dir/$newfile" 
done 

ls testing/ 

И это будет:

247639260 
berra.txt gusten.txt nisse.txt 
testing/berra.txt testing berra.txt 247639260berra.txt 
testing/guste.txt testing guste.txt 247639260guste.txt 
testing/nisse.txt testing nisse.txt 247639260nisse.txt 
247639260berra.txt 247639260guste.txt 247639260nisse.txt 

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

Смежные вопросы