Форум русскоязычного сообщества Ubuntu


Автор Тема: bash, работа с именами файлов  (Прочитано 2859 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн trablshuter

  • Автор темы
  • Новичок
  • *
  • Сообщений: 33
  • Ubuntu Server 16.04
    • Просмотр профиля
bash, работа с именами файлов
« : 02 Июнь 2016, 10:41:56 »
Подскажите пожалуйста, как узнавать количество символов в имени файла?

PS: в целом необходимо, в указанной директории перебрать все файлы, и те файлы чьи именасодержат символов больше заданного - переименовать взяв их же старые ("длинные" имена, но обрезав с начала на нужное количество символов)...  Но пока не представляю в стороны каких команд копать...

Оффлайн EvangelionDeath

  • Администратор
  • Старожил
  • *
  • Сообщений: 3096
  • Ubuntu Mate 16.04 х64
    • Просмотр профиля
Re: bash, работа с именами файлов
« Ответ #1 : 02 Июнь 2016, 11:28:46 »
name='my_some_file111111111111.txt'

Определение количества символов:

${#name}

Обрезать:

echo $name | cut -c 1-8


Код: Bash
  1. #!/bin/bash
  2.  
  3. for file in `ls -alF | grep '^-' | awk '{print $9}'`; do
  4.     newfile=`echo $file | cut -c 1-12`
  5.     mv $file $newfile
  6. done
  7.  

Как то так. Может есть и более элегантные решения (кроме того тут не обращалось внимания на расширения файлов)
« Последнее редактирование: 02 Июнь 2016, 11:32:45 от EvangelionDeath »
Fujitsu UH552: Intel Core i3-3217U, 16GB DDR3 1600MHz, Intel HD4000, Intel 535 120GB/Ubuntu 16.04 Mate
HP 625: AMD Athlon P320, 4GB DDR3 1333MHz, AMD HD4250, Seagate Momentus/Ubuntu 14.04 Mate

Оффлайн trablshuter

  • Автор темы
  • Новичок
  • *
  • Сообщений: 33
  • Ubuntu Server 16.04
    • Просмотр профиля
Re: bash, работа с именами файлов
« Ответ #2 : 02 Июнь 2016, 11:44:43 »
СПС !  пригодится...

перебор самих файлов вот такой ещё нашел:
for file in `find "/etc/" -type f`
do
echo ${#file};
done
но, опять же нужен рекурсивный поиск, а она вроде этого не делает... на эту тему пока не гуглил :(

может есть какие команды для вырезания пути и имени файла в bash-e, чтобы не городить циклы из expr index $file / и кучи всего, чего там ещё понадобиться.... 
т.е., например, есть путь: "/dir1/dir2/dir3/dir4/file1.txt"
и сразу из этой строки выводить это, без всяких кувырканий со строкой:
Patch="/dir1/dir2/dir3/dir4"
NameFile="file1.txt"
NameFileNoExp="file1"

а может к каким-то командам терминальным есть флаги, с которыми они выводят именно такие
« Последнее редактирование: 02 Июнь 2016, 11:49:10 от trablshuter »

Оффлайн EvangelionDeath

  • Администратор
  • Старожил
  • *
  • Сообщений: 3096
  • Ubuntu Mate 16.04 х64
    • Просмотр профиля
Re: bash, работа с именами файлов
« Ответ #3 : 02 Июнь 2016, 11:56:18 »
Код: Bash
  1. man dirname
  2. man basename
  3.  
Fujitsu UH552: Intel Core i3-3217U, 16GB DDR3 1600MHz, Intel HD4000, Intel 535 120GB/Ubuntu 16.04 Mate
HP 625: AMD Athlon P320, 4GB DDR3 1333MHz, AMD HD4250, Seagate Momentus/Ubuntu 14.04 Mate

Оффлайн Pilot6

  • Старожил
  • *
  • Сообщений: 11169
    • Просмотр профиля
Re: bash, работа с именами файлов
« Ответ #4 : 02 Июнь 2016, 11:56:46 »
trablshuter,
Есть масса команд для этого. Чтобы вырезать только имя файла можно например использовать команду basename.

basename /dir1/dir2/dir3/dir4/file

выведет

file.

Ну и в предыдущем посте про dirname уже сказали.
Я в личке не консультирую. Вопросы задавайте на форуме.

Оффлайн trablshuter

  • Автор темы
  • Новичок
  • *
  • Сообщений: 33
  • Ubuntu Server 16.04
    • Просмотр профиля
Re: bash, работа с именами файлов
« Ответ #5 : 02 Июнь 2016, 12:05:52 »
dirname
basename
отлично, то о чём и мечтал  ;D
Вот Вам благодАр люди добрые !   :D
« Последнее редактирование: 02 Июнь 2016, 12:08:54 от trablshuter »

Оффлайн Azure

  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 5661
  • elementaryOS 0.4 Loki, i3wm on Debian9
    • Просмотр профиля
Re: bash, работа с именами файлов
« Ответ #6 : 02 Июнь 2016, 13:19:59 »
Обрезать:
echo $name | cut -c 1-8
А так хорошо начали:
Определение количества символов:${#name}
;)${name::8}В общем
Код: Bash
  1. len=16
  2. find -type f -exec bash -c '
  3.    fname=${0##*/}
  4.    [ ${#fname} -gt "$len" ] && {
  5.        tmp=${fname%.*}
  6.        ext=${fname#$tmp}
  7.        echo mv "$0" "${0%$fname}${tmp::$(($len-${#ext}))}$ext"
  8.    }
  9.    ' {} \;
« Последнее редактирование: 02 Июнь 2016, 13:37:39 от Azure »
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн EvangelionDeath

  • Администратор
  • Старожил
  • *
  • Сообщений: 3096
  • Ubuntu Mate 16.04 х64
    • Просмотр профиля
Re: bash, работа с именами файлов
« Ответ #7 : 02 Июнь 2016, 13:28:07 »
Azure,
(Нажмите, чтобы показать/скрыть)
Fujitsu UH552: Intel Core i3-3217U, 16GB DDR3 1600MHz, Intel HD4000, Intel 535 120GB/Ubuntu 16.04 Mate
HP 625: AMD Athlon P320, 4GB DDR3 1333MHz, AMD HD4250, Seagate Momentus/Ubuntu 14.04 Mate

Оффлайн Cxms

  • Активист
  • *
  • Сообщений: 407
    • Просмотр профиля
Re: bash, работа с именами файлов
« Ответ #8 : 02 Июнь 2016, 13:36:19 »
ls -alF | grep '^-' | awk '{print $9}'пффф...
find -type f
cut -c 1-NНе обрезает с начала строку, а выводит подстроку от 1 до N-го символа,
и неправильно работает с русскими символами:
echo -n 'Имя какого-то файла.txt' | cut -c 1-8
Вывести имена файлов и дир. длинее 32 симолов:
find -printf "%f\n" | sed -n '/^.\{32\}/p'
Azure,
файл: "$dname${tmp::$(($len-${#ext}))}$ext"
может уже существовать :D (и не один раз).

Оффлайн EvangelionDeath

  • Администратор
  • Старожил
  • *
  • Сообщений: 3096
  • Ubuntu Mate 16.04 х64
    • Просмотр профиля
Re: bash, работа с именами файлов
« Ответ #9 : 02 Июнь 2016, 14:13:39 »
Cxms,
(Нажмите, чтобы показать/скрыть)

Напишите скрипт, где все будет "правильно". Просили помощи в написании, а не саму полную реализацию
« Последнее редактирование: 02 Июнь 2016, 14:17:06 от EvangelionDeath »
Fujitsu UH552: Intel Core i3-3217U, 16GB DDR3 1600MHz, Intel HD4000, Intel 535 120GB/Ubuntu 16.04 Mate
HP 625: AMD Athlon P320, 4GB DDR3 1333MHz, AMD HD4250, Seagate Momentus/Ubuntu 14.04 Mate

Оффлайн Cxms

  • Активист
  • *
  • Сообщений: 407
    • Просмотр профиля
Re: bash, работа с именами файлов
« Ответ #10 : 02 Июнь 2016, 15:10:12 »
EvangelionDeath,
(Нажмите, чтобы показать/скрыть)
« Последнее редактирование: 02 Июнь 2016, 15:14:40 от Cxms »

Оффлайн Azure

  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 5661
  • elementaryOS 0.4 Loki, i3wm on Debian9
    • Просмотр профиля
Re: bash, работа с именами файлов
« Ответ #11 : 02 Июнь 2016, 15:56:00 »
3. awk '{print substr($0,<from>,<length>)}' - тот-же баг.
И где такой код вы находите? ???
Код: Bash
  1. awk 'BEGIN{FS=""}{for(i=1;i<len;i++)printf("%s",$i);print $len}' len=8

Пользователь добавил сообщение 02 Июнь 2016, 16:00:22:
А если sed я бы использовал более быстрый кодsed 's/./\n/9;P;d'
« Последнее редактирование: 02 Июнь 2016, 16:00:22 от Azure »
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн Cxms

  • Активист
  • *
  • Сообщений: 407
    • Просмотр профиля
Re: bash, работа с именами файлов
« Ответ #12 : 02 Июнь 2016, 16:21:42 »
trablshuter,
Код: Bash
  1. # Максимальная длина имени файла
  2. MAX_L=20
  3.  
  4. IFS=$'\n'
  5. for F in $(find "$PWD" -type f)
  6. do
  7.         FN="$(basename "$F")"
  8.         if [ ${#FN} -gt $MAX_L ]
  9.         then
  10.                 FD="$(dirname "$F")"
  11.                 # Новое имя файла - MAX_L символов от конца
  12.                 NFN="$(echo "$FN" | egrep -o ".{$MAX_L}$" | tr -d '\n')"
  13.                 if [ -f "$FD/$NFN" ]
  14.                 then
  15.                         N=2
  16.                         # Пока файл с таким именем существует - добавляем в начало число от 2 и более
  17.                         # Но после этого длина становится больше MAX_L символов
  18.                         while [ -f "$FD/$N$NFN" ]; do let N+=1; done
  19.                         NFN="$N$NFN"
  20.                 fi
  21.                 # Переименовываем файл
  22.                 mv "$F" "$FD/$NFN"
  23.                 echo "\"$FN\" переименовано в \"$NFN\""
  24.         fi
  25. done
  26.  

Azure,
Цитировать
sed 's/./\n/9;P;d'
а с конца как?
« Последнее редактирование: 02 Июнь 2016, 16:39:13 от Cxms »

Оффлайн EvangelionDeath

  • Администратор
  • Старожил
  • *
  • Сообщений: 3096
  • Ubuntu Mate 16.04 х64
    • Просмотр профиля
Re: bash, работа с именами файлов
« Ответ #13 : 02 Июнь 2016, 16:36:53 »
(Нажмите, чтобы показать/скрыть)
Образец для подражания =)

И с авком не знаю, что у Вас не работает. man locale

Код: Bash
  1. #!/bin/bash                                                                                                                                                                                    
  2.  
  3. len=12
  4. add=0
  5. IFS=$'\n'
  6. olddir=''
  7. for file in `find $1 -type f | sort` ; do
  8.     fname=`basename $file`
  9.     [ ${#fname} -gt "$len" ] && {
  10.         tmp=${fname%.*}
  11.         ext=${fname#$tmp}
  12.         dest="${file%$fname}${tmp::$(($len-${#ext}))}$ext"
  13.         if [ -f $dest ]; then
  14.             if [ "$olddir" = `dirname $file` ]; then
  15.                 let add+=1
  16.             else
  17.                 olddir=`dirname $file`
  18.                 add=1
  19.             fi
  20.             while [ -f "${file%$fname}${tmp::$(($len-${#ext}-${#add}))}$add$ext" ]; do
  21.                 let add+=1;
  22.             done
  23.             mv "$file" "${file%$fname}${tmp::$(($len-${#ext}-${#add}))}$add$ext"
  24.             echo "File moved from $file to ${file%$fname}${tmp::$(($len-${#ext}-${#add}))}$add$ext"
  25.         else
  26.             mv "$file" "${file%$fname}${tmp::$(($len-${#ext}))}$ext"
  27.             echo "File moved from $file to ${file%$fname}${tmp::$(($len-${#ext}))}$ext"
  28.         fi
  29.     }  
  30. done
  31.  
  32.  
« Последнее редактирование: 02 Июнь 2016, 19:24:59 от EvangelionDeath »
Fujitsu UH552: Intel Core i3-3217U, 16GB DDR3 1600MHz, Intel HD4000, Intel 535 120GB/Ubuntu 16.04 Mate
HP 625: AMD Athlon P320, 4GB DDR3 1333MHz, AMD HD4250, Seagate Momentus/Ubuntu 14.04 Mate

Оффлайн Cxms

  • Активист
  • *
  • Сообщений: 407
    • Просмотр профиля
Re: bash, работа с именами файлов
« Ответ #14 : 02 Июнь 2016, 16:54:23 »
EvangelionDeath,
Да, но зато файлы не будут затерты как в варианте от Azure.
Т.к при переименовании:
mv "/путь/имя_файла" "/путь/новое_обрезаное_имя_файла"файл "/путь/новое_обрезаное_имя_файла" если он уже существовал, будет затерт.

 

Страница сгенерирована за 0.104 секунд. Запросов: 25.