如何重命名目录中所有带有特殊字符和空格的文件?


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重命名脚本(请参考:manpages.ubuntu.com/manpages/dapper/man1/prename.1.html),但是却正在获取util-linux重命名,其工作方式不同。
杰夫·谢勒

Answers:


10

-n标志是

-无所作为

无操作:显示要重命名的文件。

因此,如果没有任何更改,这是正常的。

关于您的命令,它对我有用:

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

也许取决于您的外壳,您必须转义|

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

或者,您可以使用该[…]符号对字符进行分组:

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

1
我尝试了所有三个不带-n选项的选项,但仍然不会更改文件名。对于上述3种类型,我都不会给出任何错误。也许由于某些原因,rename命令不起作用。还有其他方法可以更改目录中名称中带有空格或$或@的所有文件吗?
Ankit Vashistha 2015年

@AnkitVashistha rename -n 's/./_/g' *输出一些东西吗?
fredtantini

它什么也没给出,没有输出,没有错误。它只是落在下一个命令行上。
Ankit Vashistha

在Ubuntu 18.04,Bash 4.4.20(1)-release上,重命名对我来说也不适合替换(空格)或':'
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:他正在使用infile做hokus-pokus,因为linux在移动文件名时会遇到处理特殊字符的问题。


1
特殊字符 ?哪个 ?
don_crissti

空格,在符号处,“&”号....
Matthias R. Wiora

没有问题,移动文件,其中包含一个名字特殊字符(包括新行)......你可能不熟悉的炮弹(并顺便说一句,这无关的Linux,这是一个壳特征? )
don_crissti

MH好-你也许就
马蒂亚斯R. Wiora

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

现在,我编写了一个小的Shell脚本来实现这一目标。以下是代码:

#!/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 >> barsed -e S1 -e S2 -e S3 foo >> bar
Archemar

2
@Archemar-或干脆sed 's/[ ()@$]/_/g'sed 'y/ ()@$/_____/'
don_crissti

感谢don_crissti和Archemar的意见和建议。
Ankit Vashistha

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

0

对于在bash 4.4.20(1)-bash上的Ubuntu 18.04 LTS上的我来说,这种单线效果很好,可以删除空格@,:#...

测试(注意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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.