【问题标题】:star wildcard in bash [duplicate]bash中的星号通配符[重复]
【发布时间】:2018-11-01 02:38:47
【问题描述】:

我的 bash 脚本有一个小问题。我尝试将具有txt 扩展名的整个文件的当前目录中的文件名更改为text 扩展名。例如1.txt1.text

我的脚本现在看起来像这样:

#!/bin/bash
FILES=`ls /home/name/*.txt`
NAME=*.txt
RENAME=*.text

for file in FILES
do 
mv $NAME $RENAME
done

我尝试了单引号、双引号和反引号的完整组合,但我一直收到错误。

您对如何在 bash 中接收通配符“*”有一些想法吗?

谢谢。

【问题讨论】:

  • 您似乎忘记在您的代码上运行shellcheck

标签: linux bash wildcard


【解决方案1】:

这根本不是你的做法。

#!/bin/bash
shopt -s nullglob

OLD=.txt
NEW=.text
FILES=(/home/name/*"$OLD")    

for file in "${FILES[@]}"
do
  mv "$file" "${file%$OLD}$NEW}"
done

【讨论】:

    【解决方案2】:

    您的脚本存在许多问题。首先,您不应该运行ls 并尝试像那样存储它的输出。如果您想遍历这些文件,只需在循环中执行:

    for file in /home/name/*.txt
    

    现在,shell 正在为您完成所有工作,并且作为奖励处理您可能拥有的任何奇怪的文件名。

    在您的示例中,您循环的是文字字符串“FILES”,而不是变量,但我想这只是一个错字。

    更改文件名的内置方法是使用参数扩展删除旧的,然后与新的连接:

    old=txt
    new=text
    
    for file in /home/name/*"$old"
    do
        mv "$file" "${file%$old}$new"
    done
    

    如果可能没有与 glob 匹配的文件,则默认情况下,/home/name/*.txt 不会被扩展,您的循环只会运行一次。那么你有几个选择:

    • 使用shopt -s nullglob 使/home/name/*.txt 扩展为null,并跳过循环
    • 在循环内添加显式检查以确保在尝试 mv 之前存在 $file

      for file in /home/name/*"$old"
      do
          [ -e "$file" ] || continue
          mv "$file" "${file%$old}$new"
      done
      

    【讨论】:

      【解决方案3】:
      1. 您可以使用 rename 来重命名文件名。

        rename .txt .text /home/name/*.txt
        
      2. 如果你想通过循环来做到这一点,你可以

        for FILE in /data/tmp/*.txt; do
            mv  "${FILE}" "${FILE/.txt/.text}"
        done
        

      【讨论】:

      • 我已经添加了您省略的重要引用。您仍然存在参数替换将替换名称中的 first .txt 而不是最后一个的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-04
      • 1970-01-01
      • 2013-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多