MV:不能统计 - 没有此类文件或目录



我已经将LS命令的输出输送到文件中。内容就像:

[Chihiro]_Grisaia_no_Kajitsu_-_01_[1920x816_Blu-ray_FLAC][D2B961D6].mkv
[Chihiro]_Grisaia_no_Kajitsu_-_02_[1920x816_Blu-ray_FLAC][38F88A81].mkv
[Chihiro]_Grisaia_no_Kajitsu_-_03_[1920x816_Blu-ray_FLAC][410F74F7].mkv

我根据情节编号重命名这些情节的尝试如下:

cat grisaia | while read line; 
   #get the episode number
   do EP=$(echo $line | egrep -o  "_([0-9]{2})_" | cut -d "_" -f2)
   if [[ $EP ]]
      #escape special characters
      then line=$(echo $line | sed 's/[/\[/g' | sed 's/]/\]/g')
      mv "$line" "Grisaia_no_Kajitsu_${EP}.mkv"
   fi
done

带有以下错误的代码1的MV命令退出:

MV:无法统计 ' [chihiro ] _ grisaia_no_kajitsu _-- 01 [1920x816_blu-ray_flac ] [d2b961d6 ]。 没有这样的文件或目录

我真正没有得到的是,如果我复制无法统计的文件并尝试统计文件,则可以正常工作。我什至可以采用输出完全相同的字符串,并单独执行MV命令。

如果用双引号(")包围变量($line),则无需逃脱这些特殊字符。因此,您在那里有两个选择:

  1. 完全删除以下分配:

    then # line=$(echo $line | sed 's/[/\[/g' | sed 's/]/\]/g')`
    

  2. 在以下行中删除双引号:

    mv $line "Grisaia_no_Kajitsu_${EP}.mkv"
    

进一步的考虑

  1. 解析ls的输出绝不是一个好主意。考虑带有空间的文件名。有关更多信息,请参见此文档。

  2. cat这里是不必要的:

    cat grisaia | while read line; 
        ...
    done
    

    而是使用此操作以避免不必要的管道:

    while read line; 
        ...
    done < grisaia
    

为什么在某些情况下避免管道有益?(回答评论)

管道创建子壳(价格昂贵),您也可以犯一些错误:

last=""
cat grisaia | while read line; do
    last=$line
done
echo $last # surprise!! it outputs an empty string

原因是循环内的$last属于另一个子壳。

现在,请参阅相同的方法:

while read line; do
    last=$line
done < grisaia
echo $last # it works as expected and prints the last line

相关内容

  • 没有找到相关文章

最新更新