AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1499949
Accepted
DealTime444
DealTime444
Asked: 2024-01-13 21:58:16 +0800 CST2024-01-13 21:58:16 +0800 CST 2024-01-13 21:58:16 +0800 CST

在简单的 while 循环中保留文件扩展名(一行)

  • 772

我有一个简单的字符串,它将按顺序重命名文件夹中的所有 jpeg 文件:

ls -v | cat -n | while read n f; do mv -n "$f" "pic-$n.jpg"; done

但我有一个包含许多不同文件类型的文件夹。是否有一个简单的字符串或变量可以替换.jpg为以保留文件扩展名?或者现在必须是完整的脚本吗?如果可能的话,我想把它保留在一个衬垫中。

例子

假设我有一个这样的文件夹:

a long hash name.mp4
another name.m4v
video.mov
another name.mp4

等等。我想重命名这些文件,如下所示,以便它们看起来更有组织性并且没有太多字符,如下所示:

vid-1.mp4
vid-2.m4v
vid-3.mov
vid-4.mp4

如果我使用ls -v | cat -n | while read n f; do mv -n "$f" "vid-$n"; done,那么我就不会有文件扩展名。我想保留文件扩展名,因为有时打开它们更容易。

我主要想知道 bash 中是否有一个全局变量来定义文件扩展名

bash
  • 2 2 个回答
  • 43 Views

2 个回答

  • Voted
  1. Best Answer
    terdon
    2024-01-13T22:35:30+08:002024-01-13T22:35:30+08:00

    不要在这里使用循环,只需使用rename:

    $ ls
    'a bad name.png'   asdlha.gif   askd.png  'a worse'$'\n''name.jpg'   kasdjh.jpg
    
    $ rename -n 's/.*(\..+)/"pic-" . ++$a . "$1"/se' *
    a bad name.png -> pic0.png
    asdlha.gif -> pic1.gif
    askd.png -> pic2.png
    a worse
    name.jpg -> pic3.jpg
    kasdjh.jpg -> pic4.jpg
    

    如果看起来正确,请重新运行,而无需-n实际重命名。

    解释:

    该rename命令是一个 perl 脚本,可以运行 perl 代码来重命名文件。在这里,我们使用替换运算符 ( s/old/new/) 和几个特殊选项:

    • 这/s使得替换运算符将其输入视为单行,从而允许.匹配换行符。我们需要它来处理带有换行符的文件名,正如我在上面的示例中所做的那样。
    • 让/e我们将右侧 ( s/left/right/) 作为 perl 表达式进行计算。该表达式的"pic-" . ++$a . "$1"意思是“字符串pic-,然后变量的值$a加一,然后是左侧括号内匹配的内容”。在我们的例子中,是扩展。

    接下来,使用的正则表达式 ( .*(\..+)) 表示“零个或多个字符 ( .*) 直到最后一个.(\.匹配文字.),然后是一个或多个字符 ( .+)。因为最后一个\..+位于括号中,所以匹配的内容(扩展名)可用如$1右侧所示。

    在不带 的情况下运行上面的命令后-n,我留下了:

    $ rename  's/.*(\..+)/"pic-" . ++$a . "$1"/se' *
    terdon@oregano foo $ ls
    pic-1.png  pic-2.gif  pic-3.png  pic-4.jpg  pic-5.jpg
    

    或者,您可以在 shell 中使用以下命令执行此操作:

    i=1; for file in *; do 
      ext="${file##*.}"; 
      mv -- "$file" pic-$((i++))."$ext"; 
    done
    

    在这里,我们循环遍历所有文件(和目录,如果您不想重命名目录,请小心),将每个文件保存为$file. 然后,我们得到扩展名${file##*.}. 该格式将从变量 中${variable##pattern}删除 的最长匹配项。通过使用,我们删除了直到最后的所有内容,只留下我们另存为的扩展名。pattern$variable${file##*.}.$ext

    接下来,该mv命令将重命名$file为,加上我们用 初始化pic-的变量的值,加一,然后是 a和扩展名。$ii=1.

    与rename上面的解决方案一样,这也可以处理任意文件名:

    $ ls
    'a bad name.png'   asdlha.gif   askd.png  'a worse'$'\n''name.jpg'   kasdjh.jpg
    $ i=1; for file in *; do 
      ext="${file##*.}"; 
      mv -- "$file" pic-$((i++))."$ext"; 
    done
    $ ls
    pic-1.png  pic-2.gif  pic-3.png  pic-4.jpg  pic-5.jpg
    
    • 2
  2. steeldriver
    2024-01-13T23:31:45+08:002024-01-13T23:31:45+08:00

    如果您特别需要按版本排序顺序对文件进行算术命名(与 一样ls -v),那么我建议类似

    printf '%s\0' *.* | sort -zV | {
      local n=1
      while IFS= read -r -d '' f; do 
        echo mv -nv -- "$f" "pic-$((++n)).${f##*.}"
      done
    }
    

    或者,如果您想对新名称进行零填充(这使得后续排序更容易),也许

    printf '%s\0' *.* | sort -zV | { 
      local n=1
      while IFS= read -r -d '' f; do 
        printf -v p 'pic-%03d.%s' $((++n)) "${f##*.}"
        echo mv -nv -- "$f" "$p"
      done
    }
    

    echo一旦您确认将以所需的顺序处理正确的文件,请删除。如果您不关心可读性,您当然可以将它们写为“一行”(如果您愿意),例如。

    printf '%s\0' *.* | sort -zV | { local n=1; while IFS= read -r -d '' f; do printf -v p 'pic-%03d.%s' $((++n)) "${f##*.}"; echo mv -nv -- "$f" "$p"; done; }
    
    • 2

相关问题

  • 同时复制到两个位置

  • 如何在 shell 脚本中创建选择菜单?

  • 从 bash 迁移到 zsh [关闭]

  • bashrc 还是 bash_profile?

  • 备份 bash 脚本未压缩其 tarball

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve