Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux bash中的星形通配符_Linux_Bash_Wildcard - Fatal编程技术网

Linux bash中的星形通配符

Linux bash中的星形通配符,linux,bash,wildcard,Linux,Bash,Wildcard,我的bash脚本有一个小问题。我尝试将当前目录中扩展名为txt的所有文件的文件名更改为text扩展名。例如,将1.txt转换为1.text 我的脚本现在看起来像这样: #!/bin/bash FILES=`ls /home/name/*.txt` NAME=*.txt RENAME=*.text for file in FILES do mv $NAME $RENAME done 我尝试了单引号、双引号和反勾号的完整组合,我总是收到错误 您对如何在bash中接收通配符“*”有什么想法吗 谢

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

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

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

for file in FILES
do 
mv $NAME $RENAME
done
我尝试了单引号、双引号和反勾号的完整组合,我总是收到错误

您对如何在bash中接收通配符“*”有什么想法吗

谢谢

  • 可以使用“重命名”重命名文件名

    rename .txt .text /home/name/*.txt
    
  • 如果你想通过循环来实现,你可以

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

  • 你根本不是这样做的

    #!/bin/bash
    shopt -s nullglob
    
    OLD=.txt
    NEW=.text
    FILES=(/home/name/*"$OLD")    
    
    for file in "${FILES[@]}"
    do
      mv "$file" "${file%$OLD}$NEW}"
    done
    

    您的脚本存在许多问题。首先,您不应该运行
    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,并跳过循环
    • 在循环中添加一个显式检查,以确保
      $file
      存在,然后再尝试
      mv

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

    您似乎忘记在代码上运行
    shellcheck
    。我添加了您忽略的重要引用。您仍然存在这样一个问题:参数替换将替换名称中的第一个
    .txt
    ,而不是最后一个。