Как переименовать все файлы со специальными символами и пробелами в каталоге?

10

Как я могу переименовать все файлы в определенном каталоге, где файлы содержат пробелы и специальные символы ($ и @) в их именах?

Я попробовал renameследующую команду, чтобы заменить все пробелы и специальные символы на _:

$ ls -lrt
total 464
-rwxr-xr-x. 1 pmautoamtion pmautoamtion 471106 Jul 17 13:14 Bharti Blocked TRX Report Morning$AP@20150716.csv


$ rename -n 's/ |\$|@/_/g' *
$ ls -lrt
total 464
-rwxr-xr-x. 1 pmautoamtion pmautoamtion 471106 Jul 17 13:14 Bharti Blocked TRX Report Morning$AP@20150716.csv
$

Команда работает, но не вносит никаких изменений в имена файлов и также не возвращает никаких ошибок. Как можно это исправить и есть ли другие способы?

Анкит Вашиштха
источник
1
Возможно, вы ожидаете сценария переименования perl (ref: manpages.ubuntu.com/manpages/dapper/man1/prename.1.html ), но вместо этого получаете переименование util-linux, которое работает не так.
Джефф Шаллер

Ответы:

10

-nФлаг для

--no-акт

Нет действий: показать, какие файлы были бы переименованы.

Так что это нормально, если у вас нет никаких изменений.

Что касается вашей команды, она работает для меня:

$ touch "a @ test"
$ ls
a @ test
$ rename -n 's/ |\$|@/_/g' *
a @ test renamed as a___test

Может быть, в зависимости от вашей оболочки, вы должны избежать |

$ rename -n 's/ \|\$\|@/_/g' *

Или вы можете использовать […]обозначение для группировки символов:

$ rename -n 's/[ @\$]/_/g' *
fredtantini
источник
1
Я перепробовал все три без опции -n, но имя файла не изменилось. Я не даю никакой ошибки для любого из 3 типов, упомянутых выше. Возможно, команда переименования не работает по какой-то причине. Есть ли другой способ изменить все файлы в каталоге с пробелами или $ или @ в их именах?
Анкит Вашиштха
@AnkitVashistha что- rename -n 's/./_/g' *то выводит?
Фредантини
Это ничего не дает, ни вывода, ни ошибки. Это просто приземляется на следующей командной строке.
Анкит Вашиштха
Переименование также не работает для меня, чтобы заменить (пробел) или ':' в Ubuntu 18.04, Bash 4.4.20 (1) -релиз
Ouss
7

Вы можете попробовать вот так:

for file in ./*Block*                                       
do echo mv "$file" "${file//[ ()@$]/_}"
done

Если вы довольны результатом, удалите echoперед, mvчтобы фактически переименовать файлы.

оборота дон_криссти
источник
Одно из лучших решений, которое я прошел, я так долго пытался это сделать
Sushin Pv
2

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

#!/bin/bash

for file in ./*
do
  infile=`echo "${file:2}"|sed  \
         -e 's|"\"|"\\"|g' \
         -e 's| |\ |g' -e 's|!|\!|g' \
         -e 's|@|\@|g' -e 's|*|\*|g' \
         -e 's|&|\&|g' -e 's|]|\]|g' \
         -e 's|}|\}|g' -e 's|"|\"|g' \
         -e 's|,|\,|g' -e 's|?|\?|g' \
         -e 's|=|\=|g'  `
  outfileNOSPECIALS=`echo "${file:2}"|sed -e 's|[^A-Za-z0-9._-]|_|g'`
  outfileNOoe=`echo $outfileNOSPECIALS| sed -e 's|ö|oe|g'`
  outfileNOae=`echo $outfileNOoe| sed -e 's|ä|ae|g'`
  outfileNOue=`echo $outfileNOae| sed -e 's|ü|ue|g'`
  outfileNOOE=`echo $outfileNOue| sed -e 's|Ö|OE|g'`
  outfileNOAE=`echo $outfileNOOE| sed -e 's|Ä|AE|g'`
  outfileNOUE=`echo $outfileNOAE| sed -e 's|Ü|UE|g'`
  outfileNOss=`echo $outfileNOUE| sed -e 's|ß|ss|g'`
  outfile=${outfileNOss}
  if [ "$infile" != "${outfile}" ]
  then
        echo "filename changed for " $infile " in " $outfile
        mv "$infile" ${outfile}
  fi
done

exit

в результате чего:

введите описание изображения здесь

@don_crissti: он делает hokus-pokus с infile, поскольку у linux есть свои проблемы с обработкой специальных символов при перемещении имени файла.

Матиас Р. Виора
источник
1
специальные символы ? который ?
don_crissti
Пробел, В символе, Амперсанд ....
Матиас Р. Вира
Нет проблем с перемещением файла с именем, содержащим специальные символы (включая символ новой строки) ... Вы, вероятно, не знакомы с оболочками (и, кстати, это не имеет ничего общего с Linux, это функция оболочки ... )
don_crissti
Ммм, ладно - возможно, ты прав
Матиас Р. Вира,
1

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

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

anks@anks:~/anks$ ls -lrt
total 4
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$AP@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$HP@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$CH@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$KK@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:48 Bharti TRX Block Report$UW@12Jul15.csv

Теперь я написал небольшой сценарий оболочки, чтобы сделать это возможным. Ниже приведен код:

#!/bin/bash

PATH="/home/ebfijjk/anks"

# Put the old filenames in a file.
ls $PATH | grep Block >> oldValues

# Put the new names without " " or "@" or "$" in another file
cat oldValues | sed 's/\$/_/g' | sed 's/\@/_/g' | sed 's/ /_/g' >> newValues

# Create a new file with Old names and New names seperated by a #.
paste -d'#' oldValues newValues >> oldAndNew

# Read the file with both old and new names and rename them with the new names.
while IFS='#'; read oldValue newValue
do
    mv "$oldValue" "$newValue"

done < oldAndNew

rm oldValues newValues oldandNew

И это все , когда я запустить сценарий, он переименовывает все имена файлов , содержащие пробелы ( ) или $или @с _вместо этих символов.

Анкит Вашиштха
источник
Вы можете заменить cat foo | sed S1 | sed S2 | sed S3 >> barнаsed -e S1 -e S2 -e S3 foo >> bar
Archemar
2
@Archemar - или просто sed 's/[ ()@$]/_/g'илиsed 'y/ ()@$/_____/'
don_crissti
Спасибо don_crissti и Archemar за ваши комментарии и предложения.
Анкит Вашиштха,
1

Это просто удалить специальные символы из имен файлов

for file in *; do mv "$file" `echo $file | tr -cd '.A-Za-z0-9_-'` ; done
Námásté Egész-ség.mkv --> NmstEgsz-sg.mkv

поставить echoпосле, ; doчтобы проверить раньше, как:

for file in *; do echo mv "$file" `echo $file | tr -cd '.A-Za-z0-9_-'` ; done

Другое решение:

rename -v 's/[^a-zA-Z0-9\.\s_-]//g' *.* && rename -v 's/[\s]/_/g' *.*
Námásté Egész-ség.mkv --> Nmst_Egsz-sg.mkv

-n возможность проверить раньше.

ЕАПВ
источник
0

Я долго искал решение этой проблемы. Я работаю на старых закрытых системах, в которых не могут быть установлены новые пакеты. У меня нет renameкоманды. Наконец я написал скрипт, который работает со всеми введенными на клавиатуре специальными символами. ~@#$%^&*()-_=+[]{}\|;:",<.>?' Скрипт переименует каждый файл и каталог в текущем каталоге. Он заменит все специальные символы, за исключением -_.с _характером. outfile=Линия может быть изменена , чтобы использовать другой символ для замены в случае необходимости. Заменить |_|с , |.|чтобы использовать .символ, например.

#!/bin/bash

for file in ./*
do
  infile=`echo "${file:2}"|sed  \
         -e 's|"\"|"\\"|g' \
         -e 's| |\ |g' -e 's|!|\!|g' \
         -e 's|@|\@|g' -e 's|*|\*|g' \
         -e 's|&|\&|g' -e 's|]|\]|g' \
         -e 's|}|\}|g' -e 's|"|\"|g' \
         -e 's|,|\,|g' -e 's|?|\?|g' \
         -e 's|=|\=|g'  `
  outfile=`echo "${file:2}"|sed -e 's|[^A-Za-z0-9._-]|_|g'`
  mv "$infile" ${outfile} &
done

exit
ScriptKitty37
источник
0

Для меня на Ubuntu 18.04 LTS с bash 4.4.20 (1) - выпустить эту однострочную версию, которая хорошо работала для удаления пробелов, @,: # ...

Для проверки (обратите внимание на echoкоманду:

for file in ./* ; do if [[ $file == *['!'\ :@#]* ]]; then echo mv "$file" "${file//[ #()@$:]/_}"; fi; done

Выполнить:

for file in ./* ; do if [[ $file == *['!'\ :@#]* ]]; then echo mv "$file" "${file//[ #()@$:]/_}"; fi; done
Ус
источник