Bash变量未按预期运行

时间:2014-04-21 14:00:16

标签: bash scripting

我有一个bash脚本,它逐行解析文件,使用cut命令提取日期,然后使用该日期创建一个文件夹。但是,似乎我的变量没有正确填充。我有语法问题吗?非常感谢任何对外部资源的帮助或指导。

#!/bin/bash

ls | grep .mp3 | cut -d '.' -f 1 > filestobemoved

cat filestobemoved | while read line

do
    varYear= $line | cut -d '_' -f 3
    varMonth= $line | cut -d '_' -f 4
    varDay= $line | cut -d '_' -f 5

    echo $varMonth
    mkdir $varMonth'_'$varDay'_'$varYear

    cp ./$line'.mp3' ./$varMonth'_'$varDay'_'$varYear/$line'.mp3'  
done

2 个答案:

答案 0 :(得分:4)

您的代码中有许多错误和非推荐做法。请尝试以下方法:

for f in *.mp3; do
    f=${f%%.*}
    IFS=_ read _ _ varYear varMonth varDay <<< "$f"
    echo $varMonth
    mkdir -p "${varMonth}_${varDay}_${varYear}"
    cp "$f.mp3" "${varMonth}_${varDay}_${varYear}/$f.mp3"
done

答案 1 :(得分:0)

实际错误是您需要使用command substitution。例如,而不是

varYear= $line | cut -d '_' -f 3

你需要使用

varYear=$(cut -d '_' -f 3 <<< "$line")

第二个错误是$foo | some_command在其自己的行上并不意味着$foo的内容作为输入获得piped到下一个命令,而是执行作为命令命令的输出传递给下一个。

要考虑的一些最佳做法和提示:

  • Use a portable shebang line - #!/usr/bin/env bash(免责声明:这是我的回答)。
  • Don't parse ls output
  • 避免使用useless uses of cat
  • Use More Quotes™
  • 如果可以使用管道,请不要使用文件进行临时存储。它实际上要快几个数量级,如果你想要正确地执行它,通常会使代码更简单。
  • 如果必须使用文件进行临时存储,请将它们放在mktemp -d创建的目录中。最好添加trap以彻底删除临时目录。
  • 变量中不需要var前缀。
  • grep默认搜索基本正则表达式,因此.mp3匹配任何单个字符,后跟文字字符串mp3。如果要搜索点,则需要 使用grep -F搜索文字字符串或将正则表达式转义为\.mp3
  • 您通常希望使用read -r(由POSIX定义)来按字面意思处理输入中的反斜杠。