2012-05-11 4 views
1

Я знаю, что этот вопрос задан, но я не могу найти более одного решения, и он не работает для меня. По сути, я ищу Баш скрипт, который будет принимать список файлов, который выглядит следующим образом:Создайте новую последовательность файлов из существующей последовательности вместе с нумерацией

image1.jpg
image2.jpg
image3.jpg

И затем сделайте копию каждого , но число его последовательно назад. Таким образом, последовательность будет иметь три новых файлов, созданных, являются:

image4.jpg
image5.jpg
image6.jpg

И все же, image4.jpg был бы нетронутый экземпляр image3. jpg и image5.jpg нетронутая копия image2.jpg и так далее. Я уже пробовал решение, описанное в this stackoverflow question, не повезло. Я, по общему признанию, не очень далеко от пути к сценарию bash, и если я возьму кусок кода в первом указанном ответе и сделаю скрипт, я всегда получаю «2: Синтаксическая ошибка:» («неожиданно» снова и снова. я попробовал изменить синтаксис с (примерно немного, но не успел когда-либо). Так что либо я делаю что-то неправильно, либо есть лучший сценарий.

Извините, что не публиковал это ранее, но код, который я использую является:

image=(image*.jpg) 
MAX=${#image[*]} 
for i in ${image[*]} 
do 
    num=${i:5:3} # grab the digits 
    compliment=$(printf '%03d' $(echo $MAX-$num | bc)) 
    ln $i copy_of_image$compliment.jpg 
done 

и я беру этот код и вставить его в файл с нано- и добавление #/bin/Баш в качестве первой строки, затем chmod +x script и выполняется в Баш через sh script Конечно,!. в моих тестах я использую файлы соответственно t itled image1.jpg - но мне также было интересно, как применить этот скрипт к каталогу jpegs, не обязательно под названием image (integer) .jpg - в моей структуре хранения файлов большинство из них - это одно слово, за которым следует number, then .jpg, и было бы неплохо не переписывать скрипт для каждого использования.

+0

Мы не можем помочь с синтаксической ошибкой, если вы не разместите код. Пожалуйста, сделай. – tripleee

+0

Спасибо за обновление. Синтаксис массива - это basism, убедитесь, что у вас есть '#!/Bin/bash' в верхней части файла, иначе вы можете столкнуться с' sh' (или даже 'csh', на некоторых платформ). – tripleee

+0

При ближайшем рассмотрении ошибка 'sh script'; вы хотите использовать 'bash script' (или просто'./script'). – tripleee

ответ

0

Возможно, что-то вроде этого.Он будет хорошо работать для чего-то вроде script image*.jpg, где подстановочный знак соответствует набору файлов, которые соответствуют регулярному шаблону с монотонно увеличивающимися номерами одинаковой длины и менее идеально с менее регулярным подмножеством файлов в текущем каталоге. Он просто предполагает, что индекс последнего файла плюс один на общее количество имен файлов - это диапазон цифр, которые нужно перебрать.

#!/bin/sh 

# Extract number from final file name 
eval lastidx=\$$# 
tmp=${lastidx#*[!0-9][0-9]} 
lastidx=${lastidx#${lastidx%[0-9]$tmp}} 
tmp=${lastidx%[0-9][!0-9]*} 
lastidx=${lastidx%${lastidx#$tmp[0-9]}} 

num=$(expr $lastidx + $#) 
width=${#lastidx} 

for f; do 
    pref=${f%%[0-9]*} 
    suff=${f##*[0-9]} 
    # Maybe show a warning if pref, suff, or width changed since the previous file 
    printf "cp '$f' '$pref%0${width}i$suff'\\n" $num 
    num=$(expr $num - 1) 
done | 
sh 

Это sh -compatible; материал expr и вырезка подстроки впереди уродливы, но совместимы с Борном. Если вы в порядке со встроенными арифметическими и строковыми конструкциями Bash, преобразование в эту форму должно быть тривиальным.

(Чтобы быть явными, ${var%foo} возвращает значение $var с foo обрежет конец, и ${var#foo} делает подобную зачистку от начала значения. Регулярных оболочки подстановочных соответствующих операторов доступны в выражении для того, что нужно обрезать. ${#var} возвращает длину значения $var.)

+0

Это прекрасно работает. Я хотел бы на этот раз признать, что, как упоминал @userunknown, я действительно не очень опытный кодер, но я начинаю начинать.Я хотел бы извиниться, если бы я оскорбил его. Я только начинаю в этом и очень ценю, что любой желал помочь, даже если у меня было очень мало вклада. Еще раз спасибо. – user1388721

0
  • Может быть, ваши реальные данные испытаний работает от 001 до 300, но здесь у вас есть image1 2 3, и, следовательно, вы извлекаете один, а не три цифры от имени файла. Num = $ {я: 5: 1}

  • Целое арифметическое может быть сделано в Баш без вызова BC

  • $ {# изображения [@]} является более надежной, чем $ {# изображение [*]} , но здесь не должно быть разницы.
  • Я не проконсультировался со словарем, но не комплимент для вашей подруги? Противоположность - это дополнение, не так ли? :)
  • другая команда сделала ссылки - чтобы сделать копии, вызовите cp.

Код:

#!/bin/bash 
image=(image*.jpg) 
MAX=${#image[@]} 
for i in ${image[@]} 
do 
    num=${i:5:1} 
    complement=$((2*$MAX-$num+1)) 
    cp $i image$complement.jpg 
done 

Самое главное: Если это Баш, назовем его с Баш. Лучшее: сделайте shebang (как и вы), сделайте его исполняемым и назовите его ./name. Вызов с именем sh приведет к неправильному интерпретатору. Если вы не сделаете его исполняемым, назовите его имя bash.

+0

Почему вы не принимаете аргумент командной строки, чтобы сказать, какие файлы обрабатывать? Возможно, например 'image = ($ 1 * $ {2-.jpg})' – tripleee

+0

@tripleee: поскольку пользователь скопировал какой-то скрипт из другого источника и не сделал ничего, чтобы решить проблему самостоятельно. Представлял ли он план, как его решить? Шаг, где у него были проблемы для прогресса? Сценарий не удался, потому что он взял его со страницы, где имя файла было bla001.jpg, а не bla1.jpg. Он связал изображения, но не скопировал их. У вас создалось впечатление, что он заметил, что эти ошибки? Что это кодер? Или это запрос «быть моим безвозмездным кодовым»? –

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