Переименование нескольких файлов со сложными пронумерованными именами

У меня есть 365 файлов с именем

MOD11A1.A2010001.h24v06.006.2016025150444.hdf MOD11A1.A2010002.h24v06.006.2016025151748.hdf MOD11A1.A2010003.h24v06.006.2016025163706.hdf

, и я хочу переименовать эти файлы как:

modis1.hdf modis2.hdf modis3.hdf

Я использую команду mv отдельно для каждого файла переименовать их.

Как достичь этого за один раз?

6
задан 22 November 2017 в 11:16

13 ответов

Поскольку вы только заботитесь о бит A2010..., используя rename в каталоге с файлами:

rename -n 's/.*A2010*(\d+).*/modis$1.hdf/' *

Пример:

$ rename -n 's/.*A2010*(\d+).*/modis$1.hdf/' *
rename(> MOD11A1.A2010001.h24v06.006.2016025150444.hdf, modis1.hdf)
rename(> MOD11A1.A2010002.h24v06.006.2016025151748.hdf, modis2.hdf)
rename(> MOD11A1.A2010003.h24v06.006.2016025163706.hdf, modis3.hdf)
rename(> MOD11A1.A2010365.h24v06.006.2016025150444.hdf, modis365.hdf)

Запустите без [ f5], чтобы фактически переименовать файлы.

10
ответ дан 22 May 2018 в 16:02
  • 1
    Как (\ d +) фиксирует числа? Это регулярная магия? – Arronical 21 November 2017 в 15:35
  • 2
    @Arronical \d - любая цифра в регулярном выражении Perl, () - группа захвата, а предыдущая 0* принимает все начальные нули – muru 21 November 2017 в 15:37
  • 3
    Замечательно, спасибо за то, что я постоянно расширяю свои знания! – Arronical 21 November 2017 в 15:41
  • 4
    @Arronical \d просто является сокращением для [0-9], эти сокращения поддерживаются весьма повсеместно - более подробно см. regular-expressions.info . – dessert 21 November 2017 в 16:00
  • 5
    @dessert универсально слишком широк, sed и awk этого не делают, grep нуждается в -P (для Perl-совместимого RE) ... – muru 22 November 2017 в 05:49

Поскольку вы только заботитесь о бит A2010..., используя rename в каталоге с файлами:

rename -n 's/.*A2010*(\d+).*/modis$1.hdf/' *

Пример:

$ rename -n 's/.*A2010*(\d+).*/modis$1.hdf/' * rename(> MOD11A1.A2010001.h24v06.006.2016025150444.hdf, modis1.hdf) rename(> MOD11A1.A2010002.h24v06.006.2016025151748.hdf, modis2.hdf) rename(> MOD11A1.A2010003.h24v06.006.2016025163706.hdf, modis3.hdf) rename(> MOD11A1.A2010365.h24v06.006.2016025150444.hdf, modis365.hdf)

Запустите без -n, чтобы фактически переименовать файлы.

10
ответ дан 18 July 2018 в 02:53

Поскольку вы только заботитесь о бит A2010..., используя rename в каталоге с файлами:

rename -n 's/.*A2010*(\d+).*/modis$1.hdf/' *

Пример:

$ rename -n 's/.*A2010*(\d+).*/modis$1.hdf/' * rename(> MOD11A1.A2010001.h24v06.006.2016025150444.hdf, modis1.hdf) rename(> MOD11A1.A2010002.h24v06.006.2016025151748.hdf, modis2.hdf) rename(> MOD11A1.A2010003.h24v06.006.2016025163706.hdf, modis3.hdf) rename(> MOD11A1.A2010365.h24v06.006.2016025150444.hdf, modis365.hdf)

Запустите без -n, чтобы фактически переименовать файлы.

10
ответ дан 24 July 2018 в 17:41

Следующий способ использует расширение параметра bash, но он полагается на ваши имена файлов в том же формате, который вы указали, поскольку он полагается на размещение используемой числовой строки. Это не обязательно самый надежный метод. Вы также должны находиться в каталоге, содержащем файлы.

for f in MOD*.hdf; do
  num="${f:13:3}"
  mv "$f" modis"$((10#$num))".hdf
done

Или как однострочный:

for f in MOD*.hdf; do num="${f:13:3}"; mv "$f" modis"$((10#$num))".hdf ; done

Это приведет к перемещению файлов так, как вы (f3), MOD11A1.A2010002.h24v06.006.2016025151748.hdf становится modis2.hdf и т. д.

6
ответ дан 22 May 2018 в 16:02
  • 1
    Просто заметили, что вы специально выделили подсветку синтаксиса - могу ли я спросить, почему? Мнение сообщества об этом кажется совершенно ясным ... – dessert 21 November 2017 в 19:35

Вы можете использовать команду rename следующим образом:

$ rename -n 's/MOD11A1\.A2010(...)\..*/modis$1.hdf/' MOD*.hdf
rename(MOD11A1.A2010001.h24v06.006.2016025150444.hdf, modis001.hdf)
rename(MOD11A1.A2010002.h24v06.006.2016025151748.hdf, modis002.hdf)
rename(MOD11A1.A2010003.h24v06.006.2016025163706.hdf, modis003.hdf)

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

Примечания

] s/old/new замените old на new \. literal . ... три символа, которые могут быть любыми (some chars) сохранить some chars для ссылки позже с помощью $1 Мы могли бы использовать простое регулярное выражение для соответствия первая часть имени файла в команде rename, как ответ муру. Иногда вы хотите использовать более явное выражение для различения файлов, которые вы делаете или не хотите действовать, или для уверенности, что ваше регулярное выражение не будет всасывать слишком много символов. Как правило, существует большая гибкость в решении этой проблемы.

Обратите внимание, что это не дает вам именно то, что вы просили; он поддерживает фиксированную ширину чисел. Я сделал это, потому что это хорошая идея использовать номера фиксированной ширины в именах файлов (в противном случае они будут отсортированы в запутанном виде, например, с 10 до 2) (и потому, что я не понял, как использовать rename, чтобы создать имена, которые вы действительно просили ... если я это сделаю, я обновлю ответ, ответ на вопрос муру ...).

Обратите внимание, что ответ muru , поэтому если вы используете 17.10 (или для будущих читателей, возможно, более позднюю версию), начните с запуска

sudo apt install rename
6
ответ дан 22 May 2018 в 16:02

Ниже приведен код:

для всех файлов, которые начинаются с MOD и заканчиваются на .hdf. Назначьте переменную, которая увеличит ее значение в 1 для каждого файла. mv в текущем файле в списке и изменить его имя на modis следует по номеру из переменной, следует за .hdf
#!/bin/bash 
idx=1
for file in MOD*.hdf
do
    echo mv "$file" "modis$((idx++)).hdf"
done

Примечание: приведенный выше сценарий будет echo команда, которую он планирует выполнить, вам нужно будет удалить echo из строки echo mv, чтобы выполнить действие.

Пример вывода:

mv MOD11A1.A2010001.h24v06.006.2016025150444.hdf modis1.hdf
mv MOD11A1.A2010002.h24v06.006.2016025151748.hdf modis2.hdf
mv MOD11A1.A2010003.h24v06.006.2016025163706.hdf modis3.hdf
]
5
ответ дан 22 May 2018 в 16:02
  • 1
    mv: не может stat 'MOD * .hdf': такой файл или ошибка каталога не отображается в терминале. – Vaishali Jain 21 November 2017 в 14:46
  • 2
    как использовать команду rename для достижения моей цели? – Vaishali Jain 21 November 2017 в 14:49
  • 3
    @VaishaliJain - вы выполнили вышеуказанные строки кода, в папке, на которой фактически хранятся файлы MOD11A1 ...? – Yaron 21 November 2017 в 14:51
  • 4
    @VaishaliJain - mv является rename command – Yaron 21 November 2017 в 14:53
  • 5
    @ pa4080 благодарит за ваш комментарий! Будет обновлен мой ответ, когда я буду рядом с компьютером. – Yaron 21 November 2017 в 23:39

Я создал следующий код. Я надеюсь, что читатель знаком с регулярным выражением в команде grep.

#!/bin/bash
declare -i Num
ls  | grep '.*MOD11A1.A201.*hdf' | while read fName
do
  step1=${fName##*MOD11A1.A201}
  Num=${step1%%.*}
  mv ${fName} modis${Num}.hdf
done
-2
ответ дан 22 May 2018 в 16:02
  • 1
  • 2
    @dessert: Почему голос? У меня создается впечатление, что ваши предпочтения в отношении некоторых команд умаляют ваше мнение об удобстве использования. Мое предложение полезно. Да, ls вернет имена файлов, которые могут нести специальные символы, но также будет звездочкой в ​​for i in MOD*.hdf. Тем не менее, этот ответ не проголосовали? На мой взгляд, несколько противоречиво. – WillemK 21 November 2017 в 18:32
  • 3
    @WillemK, предположим, что у вас есть имя файла, которое содержит символ новой строки: touch $'file\nname'. Когда вы повторяете вывод ls, вы получите fName="file" и fName="name", и ни один файл не существует. Когда вы сделаете for fName in *, вы правильно получите fName=$'file\nname'. ИМО - пониженные прогнозы оправданы, потому что ваш ответ - не лучшая практика. – glenn jackman 21 November 2017 в 18:42
  • 4
    @ glenn-jackman: вы правы в своем примере, но неправильно судите мой код. Кажется, вы не рассматриваете эффект grep. Вы очень хорошо знаете, что новая линия была бы перед MOD или перед файлом .hdf, чтобы файл проскользнул, но каковы шансы? – WillemK 21 November 2017 в 18:57
  • 5
    Кроме того, запись ls $pattern | while read f еще не короче или проще писать, чем for f in $pattern. – ilkkachu 21 November 2017 в 22:44

Я создал следующий код. Я надеюсь, что читатель знаком с регулярным выражением в команде grep.

#!/bin/bash declare -i Num ls | grep '.*MOD11A1.A201.*hdf' | while read fName do step1=${fName##*MOD11A1.A201} Num=${step1%%.*} mv ${fName} modis${Num}.hdf done
-2
ответ дан 18 July 2018 в 02:53

Ниже приведен код:

для всех файлов, которые начинаются с MOD и заканчиваются на .hdf. Назначьте переменную, которая увеличит ее значение в 1 для каждого файла. mv в текущем файле в списке и изменить его имя на modis следует по номеру из переменной, следует за .hdf #!/bin/bash idx=1 for file in MOD*.hdf do echo mv "$file" "modis$((idx++)).hdf" done

Примечание: приведенный выше сценарий будет echo команда, которую он планирует выполнить, вам нужно будет удалить echo из строки echo mv, чтобы выполнить действие.

Пример вывода:

mv MOD11A1.A2010001.h24v06.006.2016025150444.hdf modis1.hdf mv MOD11A1.A2010002.h24v06.006.2016025151748.hdf modis2.hdf mv MOD11A1.A2010003.h24v06.006.2016025163706.hdf modis3.hdf ]
5
ответ дан 18 July 2018 в 02:53

Вы можете использовать команду rename следующим образом:

$ rename -n 's/MOD11A1\.A2010(...)\..*/modis$1.hdf/' MOD*.hdf rename(MOD11A1.A2010001.h24v06.006.2016025150444.hdf, modis001.hdf) rename(MOD11A1.A2010002.h24v06.006.2016025151748.hdf, modis002.hdf) rename(MOD11A1.A2010003.h24v06.006.2016025163706.hdf, modis003.hdf)

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

Примечания

] s/old/new замените old на new \. literal . ... три символа, которые могут быть любыми (some chars) сохранить some chars для ссылки позже с помощью $1 Мы могли бы использовать простое регулярное выражение для соответствия первая часть имени файла в команде rename, как ответ муру. Иногда вы хотите использовать более явное выражение для различения файлов, которые вы делаете или не хотите действовать, или для уверенности, что ваше регулярное выражение не будет всасывать слишком много символов. Как правило, существует большая гибкость в решении этой проблемы.

Обратите внимание, что это не дает вам именно то, что вы просили; он поддерживает фиксированную ширину чисел. Я сделал это, потому что это хорошая идея использовать номера фиксированной ширины в именах файлов (в противном случае они будут отсортированы в запутанном виде, например, с 10 до 2) (и потому, что я не понял, как использовать rename, чтобы создать имена, которые вы действительно просили ... если я это сделаю, я обновлю ответ, ответ на вопрос муру ...).

Обратите внимание, что ответ muru , поэтому если вы используете 17.10 (или для будущих читателей, возможно, более позднюю версию), начните с запуска

sudo apt install rename
6
ответ дан 18 July 2018 в 02:53

Следующий способ использует расширение параметра bash, но он полагается на ваши имена файлов в том же формате, который вы указали, поскольку он полагается на размещение используемой числовой строки. Это не обязательно самый надежный метод. Вы также должны находиться в каталоге, содержащем файлы.

for f in MOD*.hdf; do num="${f:13:3}" mv "$f" modis"$((10#$num))".hdf done

Или как однострочный:

for f in MOD*.hdf; do num="${f:13:3}"; mv "$f" modis"$((10#$num))".hdf ; done

Это приведет к перемещению файлов так, как вы (f3), MOD11A1.A2010002.h24v06.006.2016025151748.hdf становится modis2.hdf и т. д.

6
ответ дан 24 July 2018 в 17:41
  • 1
    Просто заметили, что вы специально выделили подсветку синтаксиса - могу ли я спросить, почему? Мнение сообщества об этом кажется совершенно ясным ... – dessert 21 November 2017 в 19:35

Ниже приведен код:

для всех файлов, которые начинаются с MOD и заканчиваются на .hdf. Назначьте переменную, которая увеличит ее значение в 1 для каждого файла. mv в текущем файле в списке и изменить его имя на modis следует по номеру из переменной, следует за .hdf #!/bin/bash idx=1 for file in MOD*.hdf do echo mv "$file" "modis$((idx++)).hdf" done

Примечание: приведенный выше сценарий будет echo команда, которую он планирует выполнить, вам нужно будет удалить echo из строки echo mv, чтобы выполнить действие.

Пример вывода:

mv MOD11A1.A2010001.h24v06.006.2016025150444.hdf modis1.hdf mv MOD11A1.A2010002.h24v06.006.2016025151748.hdf modis2.hdf mv MOD11A1.A2010003.h24v06.006.2016025163706.hdf modis3.hdf ]
5
ответ дан 24 July 2018 в 17:41
  • 1
    mv: не может stat 'MOD * .hdf': такой файл или ошибка каталога не отображается в терминале. – Vaishali Jain 21 November 2017 в 14:46
  • 2
    как использовать команду rename для достижения моей цели? – Vaishali Jain 21 November 2017 в 14:49
  • 3
    @VaishaliJain - вы выполнили вышеуказанные строки кода, в папке, на которой фактически хранятся файлы MOD11A1 ...? – Yaron 21 November 2017 в 14:51
  • 4
    @VaishaliJain - mv является rename command – Yaron 21 November 2017 в 14:53
  • 5
    @ pa4080 благодарит за ваш комментарий! Будет обновлен мой ответ, когда я буду рядом с компьютером. – Yaron 21 November 2017 в 23:39

Вы можете использовать команду rename следующим образом:

$ rename -n 's/MOD11A1\.A2010(...)\..*/modis$1.hdf/' MOD*.hdf rename(MOD11A1.A2010001.h24v06.006.2016025150444.hdf, modis001.hdf) rename(MOD11A1.A2010002.h24v06.006.2016025151748.hdf, modis002.hdf) rename(MOD11A1.A2010003.h24v06.006.2016025163706.hdf, modis003.hdf)

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

Примечания

] s/old/new замените old на new \. literal . ... три символа, которые могут быть любыми (some chars) сохранить some chars для ссылки позже с помощью $1 Мы могли бы использовать простое регулярное выражение для соответствия первая часть имени файла в команде rename, как ответ муру. Иногда вы хотите использовать более явное выражение для различения файлов, которые вы делаете или не хотите действовать, или для уверенности, что ваше регулярное выражение не будет всасывать слишком много символов. Как правило, существует большая гибкость в решении этой проблемы.

Обратите внимание, что это не дает вам именно то, что вы просили; он поддерживает фиксированную ширину чисел. Я сделал это, потому что это хорошая идея использовать номера фиксированной ширины в именах файлов (в противном случае они будут отсортированы в запутанном виде, например, с 10 до 2) (и потому, что я не понял, как использовать rename, чтобы создать имена, которые вы действительно просили ... если я это сделаю, я обновлю ответ, ответ на вопрос муру ...).

Обратите внимание, что ответ muru , поэтому если вы используете 17.10 (или для будущих читателей, возможно, более позднюю версию), начните с запуска

sudo apt install rename
6
ответ дан 24 July 2018 в 17:41

Другие вопросы по тегам:

Похожие вопросы: