Bash - 用下划线替换空格,但用一个替换多个空格

Bash - 用下划线替换空格,但用一个替换多个空格

我习惯rename在文件名中的空格下划线,只需使用:

rename "s/ /_/g" * 

但我遇到一个问题,从网上下载的文件经常有多个空格。我使用了一个令人讨厌的解决方法(但仅适用于 3 个空格,这在大多数情况下就足够了),但必须有一个比以下更优雅的方法:

rename "s/   /_/g" *; rename "s/  /_/g" *; rename "s/ /_/g" *

答案1

以下对我有用:

rename 's/\s+/_/g' *

它将匹配一个到无限个空白实例

请注意,这也适用于换行符和选项卡,但是根据您的用例,我认为这会更好并且不是不需要的?但要专门匹配空间,您可以这样做:

rename 's/ +/_/g' *

答案2

IDK 是否rename可以递归工作。我在一个不带空格和一个带空格的子目录中创建了一些名称中带有空格的空文件。下面的代码适用于我用一个下划线重命名名称中含有一个或多个空格的文件,并且不会打扰名称中含有空格的子目录。

root@server <1>: /cwd# mkdir subdir1 'sub dir 2' ; touch 'subdir1/file 1' 'sub dir 2/file  2  ' 'subdir1/ f i l e 3 ' 'sub dir 2/   f  i  l  e   4   '

root@server <2>: /cwd# ls -lhR
.:
total 0
drwxr-xr-x 2 root root 80 Dec 28 00:42  subdir1
drwxr-xr-x 2 root root 80 Dec 28 00:42 'sub dir 2'

./subdir1:
total 0
-rw-r--r-- 1 root root 0 Dec 28 00:42 'file 1'
-rw-r--r-- 1 root root 0 Dec 28 00:42 ' f i l e 3 '

'./sub dir 2':
total 0
-rw-r--r-- 1 root root 0 Dec 28 00:42 'file  2  '
-rw-r--r-- 1 root root 0 Dec 28 00:42 '   f  i  l  e   4   '

root@server <3>: /cwd# find . -type f -exec echo {} \; | tee ../FILES.txt
./sub dir 2/   f  i  l  e   4
./sub dir 2/file  2
./subdir1/ f i l e 3
./subdir1/file 1

root@server <4>: /cwd# while IFS= read line ; do
> dirname="${line%/*}"
> fn=${line##*/}
> fn="${fn//+( )/_}"
> mv -v "$line" "${dirname}/${fn}"
> done < ../FILES.txt
renamed './sub dir 2/   f  i  l  e   4   ' -> './sub dir 2/_f_i_l_e_4_'
renamed './sub dir 2/file  2  ' -> './sub dir 2/file_2_'
renamed './subdir1/ f i l e 3 ' -> './subdir1/_f_i_l_e_3_'
renamed './subdir1/file 1' -> './subdir1/file_1'

root@server <5>: /cwd# ls -lhR
.:
total 0
drwxr-xr-x 2 root root 80 Dec 28 00:42  subdir1
drwxr-xr-x 2 root root 80 Dec 28 00:42 'sub dir 2'

./subdir1:
total 0
-rw-r--r-- 1 root root 0 Dec 28 00:42 file_1
-rw-r--r-- 1 root root 0 Dec 28 00:42 _f_i_l_e_3_

'./sub dir 2':
total 0
-rw-r--r-- 1 root root 0 Dec 28 00:42 file_2_
-rw-r--r-- 1 root root 0 Dec 28 00:42 _f_i_l_e_4_

每个命令的一些注释:

  1. 创建两个子目录,其中第二个子目录的名称中包含空格。

  2. 递归列出内容。请注意,单引号用于包含空格的文件或文件夹。

  3. 用于find查找文件 ( -type f) 并将名称回显到父目录中的“FILES.txt”。

  4. 使用while循环遍历文件中的每一行。IFS=清除输入字段分隔符,因此前导和尾随空格不会被截断。

    4.1 提取目录名,不要修改

    4.2 获取文件名

    4.3 将文件名中的一个或多个连续空格字符替换为单个下划线

    4.4 详细重命名文件,但不重命名文件夹。

  5. 递归列出内容。请注意,单引号用于包含空格的文件或文件夹。

我使用参数扩展来获取目录名称和文件名而不是dirnameand ,basename因为它更快。

相关内容