2016-11-26 9 views
1

У меня есть файлы типа .csv, но они называются по-разному. В идеале я хотел бы, чтобы скрипт нашел все файлы с CSV-типом и переименовал файл, используя его путь.Переименовать файлы с именем пути

Когда файлы переименовываются они должны быть чем-то вроде этого:

/home/doc/funds2015/folder xxx/folder 123/Folder xxx/something1.csv 
/home/doc/funds2015/folder xxx/folder 123/Folder xxx/something2.csv  
xxx_123_01_01.csv 
xxx_123_02_01.csv 

Может кто-то помочь мне реструктуризировать этот код, чтобы сделать это в одном чистом цикле. Я довольно новичок в bash.

oldpath= "/home/doc/funds2015" 

for file in $(find $oldpath -type f -name something1.csv); do 
    shortname=${file#$oldpath/} 
    newname="${shortname "some reg ex"}" 

    if [ -f $newname ]; then 
      echo "$newname already exists." 
    else 
      echo "copy: $file" 
      echo " --> $newname" 
      cp $file $newname 
    fi 
done 

for file in $(find $oldpath -type f -name something2.csv); do 
    shortname=${file#$oldpath/} 
    newname="$oldpath "some reg ex"}" 

    if [ -f $newname ]; then 
     echo "$newname already exists." 
    else 
     echo "copy: $file" 
     echo " --> $newname" 
     cp $file $newname 
    fi 
done 
+0

В ваших путях файлов есть два бита «xxx», и вы, например, вывод, в нем есть один «xxx». Какой «xxx» вы хотите? – spinkus

+0

Мне нужен только первый «xxx» и добавить «_01» в конец всех CSV-файлов –

ответ

0

Вам не нужен петля.

Вы можете использовать команду rename, retrieve и повторно использовать любое выражение с выражением perl.

Вот некоторые примеры такого выражения:

rename -n "s/^.*([0-9]{3}).*$/Clannad_c\$1/" * 
rename -n "s/^(.*)c([0-9]{3})\/(.*)$/\$1c\$2\/Clannad_c\$2p\$3/" */* 
rename -n "s/(.*)\/(.*)/\$1\/\$1p\$2/" */* 
rename -n "s/^.*([0-9]{4}).*$/Hajime\ no\ Ippo_c\$1/" * 
rename -n "s/(c[0-9]{3}_p[0-9]{2}.jpg)$/v38_\$1/" Vagabond_v38*/* 

Вы можете соответствовать любой части пути или имени файла с() и повторно использовать его с $ 1, $ 2, ... А с использованием оболочки расширения, вам даже не понадобится цикл (/).

Если бы я придерживался чего-то более близкого к тому, что вы пробовали, я бы использовал команду find и ее опцию -exec.

Вот пример:

find "$sourceDir*v0$volumeNumber*" -type f -name "*.(jpg|png)" -exec zip --quiet -r $newVolume {} + 

Эта команда найти некоторые JPG и PNG файлов и застегнул их.

0

просто мысль (без материала для петли). есть ли только один файл в каждой папке? вы можете проверить basename и dirname команды. возможно, кроме tr. нравится:

dirname /home/doc/folder12/folder34/file.csv | tr "/" "_" 

дает путь (без имени файла часть)

basename /home/doc/folder12/folder34/file.csv 

дает имя файла только без пути

так,

path_reformatted=$(dirname /home/doc/folder12/folder34/file.csv | tr "/" "_") 

filename=$(basename /home/doc/folder12/folder34/file.csv | tr "/" "_") 

new_filename=$path_reformatted$filename 
mv $old_filename $new_filename 

что вернет полезное имя файла?