Добавить в префикс имя файла имя его каталога

Код python ниже проверяет вывод acpi -i. если нет выхода: «Где моя батарея?» печатается, иначе «OK, present». Конечно, вы можете поместить любую команду там, используя либо subprocess.call(), либо subprocess.Popen().

#!/usr/bin/env python

import subprocess

get_batterystatus = subprocess.check_output(['acpi', '-i']).decode('utf-8').strip()

if get_batterystatus == "":
    print "Where is my battery?" 
else:
    print "OK, present" 
0
задан 23 January 2018 в 23:17

12 ответов

Вот немного улучшенная версия вашего скрипта - основные отличия:

, используя оболочку glob * вместо $(ls) - см. Bash Pitfall # 1, цитирующую любые расширения переменных (разрешает имена файлов с пробелы или другие забавные символы - см. Bash Pitfall # 2), обозначающие конец опций mv с помощью расширения -- GNU - это позволяет обрабатывать имена файлов, которые начинаются с дефиса также

Итак

for d in *; do 
  [[ -d "$d" ]] && cd "$d" || continue
  for f in *.mp4; do 
    echo mv -v -- "${f}" "${d}_${f}"
  done
  cd -
done

Или, более переносимо, вы можете зацикливаться на ./*.mp4, чтобы защитить от ведущих дефис, - но тогда вы должны отключить его во время mv

for d in *; do 
  [ -d "$d" ] && cd "$d" || continue
  for f in ./*.mp4; do 
    echo mv -v "${f}" "${d}_${f#./}"
  done
  cd -
done

In в любом случае удалите echo (и -v, если хотите), как только вы убедитесь, что он работает так, как вы ожидаете.

3
ответ дан 22 May 2018 в 15:21

Вот немного улучшенная версия вашего скрипта - основные отличия:

, используя оболочку glob * вместо $(ls) - см. Bash Pitfall # 1, цитирующую любые расширения переменных (разрешает имена файлов с пробелы или другие забавные символы - см. Bash Pitfall # 2), обозначающие конец опций mv с помощью расширения -- GNU - это позволяет обрабатывать имена файлов, которые начинаются с дефиса также

Итак

for d in *; do [[ -d "$d" ]] && cd "$d" || continue for f in *.mp4; do echo mv -v -- "${f}" "${d}_${f}" done cd - done

Или, более переносимо, вы можете зацикливаться на ./*.mp4, чтобы защитить от ведущих дефис, - но тогда вы должны отключить его во время mv

for d in *; do [ -d "$d" ] && cd "$d" || continue for f in ./*.mp4; do echo mv -v "${f}" "${d}_${f#./}" done cd - done

In в любом случае удалите echo (и -v, если хотите), как только вы убедитесь, что он работает так, как вы ожидаете.

3
ответ дан 17 July 2018 в 22:24

Вот немного улучшенная версия вашего скрипта - основные отличия:

, используя оболочку glob * вместо $(ls) - см. Bash Pitfall # 1, цитирующую любые расширения переменных (разрешает имена файлов с пробелы или другие забавные символы - см. Bash Pitfall # 2), обозначающие конец опций mv с помощью расширения -- GNU - это позволяет обрабатывать имена файлов, которые начинаются с дефиса также

Итак

for d in *; do [[ -d "$d" ]] && cd "$d" || continue for f in *.mp4; do echo mv -v -- "${f}" "${d}_${f}" done cd - done

Или, более переносимо, вы можете зацикливаться на ./*.mp4, чтобы защитить от ведущих дефис, - но тогда вы должны отключить его во время mv

for d in *; do [ -d "$d" ] && cd "$d" || continue for f in ./*.mp4; do echo mv -v "${f}" "${d}_${f#./}" done cd - done

In в любом случае удалите echo (и -v, если хотите), как только вы убедитесь, что он работает так, как вы ожидаете.

3
ответ дан 23 July 2018 в 23:02

Проблема решена с использованием следующего скрипта:

for i in $(ls); do                                                 
  if [ -d $i ]; then                      
     fname=${i##*/}                 
     echo $fname                           
     cd $i                                       
     for z in *.mp4; do               
       echo $z  
       cp $z ${fname}_${z}
       rm $z                   
     done                                        
     cd ..                                         
  fi                                              
done
1
ответ дан 22 May 2018 в 15:21
  • 1
  • 2
    @steeldriver, проблема с этим решением, он не добавляет каталог префикса к файлам, начинающимся с '-', и не обрабатывает каталоги, содержащие пробелы, такие как следующий путь «ходьба», – Joseph 23 January 2018 в 17:59

Предполагая, что вы находитесь в каталоге, содержащем все эти каталоги dancing, writing и т. д., команда

for folder in $(find -mindepth 1 -type d); do
  cd $folder
  PRE=${folder#./}
  for file in *; do
    mv "$file" "${PRE}_$file"
  done
  cd ..
done

выполнит то, что вы хотите. Я тестировал его, и он работал, даже когда имена файлов содержали пробелы или символы новой строки. Он не работал с такими символами в именах папок, хотя, например, walking slowly.

Изменить: предыдущий код не обрабатывает пробелы или символы новой строки в именах папок. Чтобы покрыть это, используйте модифицированный код

for folder in *; do
  if [ -d "$folder" ]; then
    cd "$folder"
    PRE=${folder#./}
    for file in *; do
      mv "$file" "${PRE}_$file"
    done
    cd ..
  fi
done

Edit: Если имя файла начинается с - (тире), команда может интерпретировать его как параметр. Чтобы справиться с ведущими тире, вставьте -- между командой mv и ее аргументами. Это говорит о том, что mv останавливает сканирование параметров.

Таким образом, конечный код:

for folder in *; do
  if [ -d "$folder" ]; then
    cd "$folder"
    for file in *; do
      mv -- "$file" "${folder}_$file"
    done
    cd ..
  fi
done
0
ответ дан 22 May 2018 в 15:21
  • 1
    @Stephan, спасибо за ваш ответ. Однако он добавляет 'have' к именам папок и не добавляет каталог префикса к файлам, начинающимся с '-'. – Joseph 23 January 2018 в 17:56
  • 2
    @Joseph: замените первую строку на for folder in *; do и окружайте тело цикла for оператором if [ -d "$folder" ], как и в вашем ответе. Это должно заботиться о пространствах в именах папок. – Stefan Hamcke 23 January 2018 в 18:21
  • 3
    Проблема с вашим решением заключается в том, что он не обрабатывает только текущий каталог, но из корня '/' – Joseph 23 January 2018 в 18:26
  • 4
    @Joseph: Я забыл использовать двойные кавычки в инструкции cd. Я действительно рекомендую читать связанные страницы соседа. – Stefan Hamcke 23 January 2018 в 18:46
  • 5
    @Joseph: Я приложил решение, как бороться с ведущими тире. – Stefan Hamcke 23 January 2018 в 19:13

Используйте find и prename:

find DIR... -mindepth 1 -type f | prename -n 's/([^\/]+)\/([^\/]+)$/$1\/$1_$2/'

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

0
ответ дан 22 May 2018 в 15:21

Используйте find и prename:

find DIR... -mindepth 1 -type f | prename -n 's/([^\/]+)\/([^\/]+)$/$1\/$1_$2/'

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

0
ответ дан 17 July 2018 в 22:24

Проблема решена с использованием следующего скрипта:

for i in $(ls); do if [ -d $i ]; then fname=${i##*/} echo $fname cd $i for z in *.mp4; do echo $z cp $z ${fname}_${z} rm $z done cd .. fi done
1
ответ дан 17 July 2018 в 22:24

Предполагая, что вы находитесь в каталоге, содержащем все эти каталоги dancing, writing и т. д., команда

for folder in $(find -mindepth 1 -type d); do cd $folder PRE=${folder#./} for file in *; do mv "$file" "${PRE}_$file" done cd .. done

выполнит то, что вы хотите. Я тестировал его, и он работал, даже когда имена файлов содержали пробелы или символы новой строки. Он не работал с такими символами в именах папок, хотя, например, walking slowly.

Изменить: предыдущий код не обрабатывает пробелы или символы новой строки в именах папок. Чтобы покрыть это, используйте модифицированный код

for folder in *; do if [ -d "$folder" ]; then cd "$folder" PRE=${folder#./} for file in *; do mv "$file" "${PRE}_$file" done cd .. fi done

Edit: Если имя файла начинается с - (тире), команда может интерпретировать его как параметр. Чтобы справиться с ведущими тире, вставьте -- между командой mv и ее аргументами. Это говорит о том, что mv останавливает сканирование параметров.

Таким образом, конечный код:

for folder in *; do if [ -d "$folder" ]; then cd "$folder" for file in *; do mv -- "$file" "${folder}_$file" done cd .. fi done
0
ответ дан 17 July 2018 в 22:24

Используйте find и prename:

find DIR... -mindepth 1 -type f | prename -n 's/([^\/]+)\/([^\/]+)$/$1\/$1_$2/'

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

0
ответ дан 23 July 2018 в 23:02

Проблема решена с использованием следующего скрипта:

for i in $(ls); do if [ -d $i ]; then fname=${i##*/} echo $fname cd $i for z in *.mp4; do echo $z cp $z ${fname}_${z} rm $z done cd .. fi done
1
ответ дан 23 July 2018 в 23:02
  • 1
  • 2
    @steeldriver, проблема с этим решением, он не добавляет каталог префикса к файлам, начинающимся с '-', и не обрабатывает каталоги, содержащие пробелы, такие как следующий путь «ходьба», – Joseph 23 January 2018 в 17:59

Предполагая, что вы находитесь в каталоге, содержащем все эти каталоги dancing, writing и т. д., команда

for folder in $(find -mindepth 1 -type d); do cd $folder PRE=${folder#./} for file in *; do mv "$file" "${PRE}_$file" done cd .. done

выполнит то, что вы хотите. Я тестировал его, и он работал, даже когда имена файлов содержали пробелы или символы новой строки. Он не работал с такими символами в именах папок, хотя, например, walking slowly.

Изменить: предыдущий код не обрабатывает пробелы или символы новой строки в именах папок. Чтобы покрыть это, используйте модифицированный код

for folder in *; do if [ -d "$folder" ]; then cd "$folder" PRE=${folder#./} for file in *; do mv "$file" "${PRE}_$file" done cd .. fi done

Edit: Если имя файла начинается с - (тире), команда может интерпретировать его как параметр. Чтобы справиться с ведущими тире, вставьте -- между командой mv и ее аргументами. Это говорит о том, что mv останавливает сканирование параметров.

Таким образом, конечный код:

for folder in *; do if [ -d "$folder" ]; then cd "$folder" for file in *; do mv -- "$file" "${folder}_$file" done cd .. fi done
0
ответ дан 23 July 2018 в 23:02
  • 1
    @Stephan, спасибо за ваш ответ. Однако он добавляет 'have' к именам папок и не добавляет каталог префикса к файлам, начинающимся с '-'. – Joseph 23 January 2018 в 17:56
  • 2
    @Joseph: замените первую строку на for folder in *; do и окружайте тело цикла for оператором if [ -d "$folder" ], как и в вашем ответе. Это должно заботиться о пространствах в именах папок. – Stefan Hamcke 23 January 2018 в 18:21
  • 3
    Проблема с вашим решением заключается в том, что он не обрабатывает только текущий каталог, но из корня '/' – Joseph 23 January 2018 в 18:26
  • 4
    @Joseph: Я забыл использовать двойные кавычки в инструкции cd. Я действительно рекомендую читать связанные страницы соседа. – Stefan Hamcke 23 January 2018 в 18:46
  • 5
    @Joseph: Я приложил решение, как бороться с ведущими тире. – Stefan Hamcke 23 January 2018 в 19:13

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

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