遇到了本应是简单的 Bash 脚本的问题

遇到了本应是简单的 Bash 脚本的问题

我对以下脚本的一个片段有疑问。每个 echo->grep-> 都是为了帮助我找出脚本未能按预期执行的地方而编写的。它被设计为更大循环的一部分,但为了理智起见,我这里只列出了与我的问题相关的部分。

我有一些文件,/var/www/acpog/upload其名称0SCAN2013后跟其余日期(YYYYMMDDHHmmSS)

该文件./alt_upcs.csv有两列,一列是 sku(1419),第二列是 UPC(9781844484201)

如果我无法在/var/www/acpog/uploads/sku 中找到匹配项,我想尝试查找 UPC 的匹配项。如果失败,我想尝试查找 sku 的匹配项,并在左侧填充零。

以下是代码片段:

st="0"
id="1419"
sd="SCAN2013"

echo "grep \"^$id,\" /var/www/acpog/upload/$st$sd* | cut -d',' -f 4-5 | tail -1"
grep "^$id," /var/www/acpog/upload/$st$sd* | cut -d',' -f 4-5 | tail -1
dt=$(grep "^$id," /var/www/acpog/upload/$st$sd* | cut -d',' -f 4-5 | tail -1)

if [ "$dt" == "" ]
then
  echo "grep \"^$id,\" alt_upcs.csv | cut -d',' -f 2"
  grep "^$id," alt_upcs.csv | cut -d',' -f 2
  u=$(grep "^$id," alt_upcs.csv | cut -d',' -f 2)
  for j in $(grep "^$id," alt_upcs.csv | cut -d',' -f 2)
  do
    if [ "$dt" == "" ]
    then
      echo "grep \"^$j,\" /var/www/acpog/upload/$st$sd* | cut -d',' -f 4-5 | tail -1"
      grep "$j" /var/www/acpog/upload/$st$sd* | cut -d',' -f 4-5 | tail -1
      dt=$(grep $j /var/www/acpog/upload/$st$sd* | cut -d',' -f 4-5 | tail -1)
    fi
  done
fi

if [ "$dt" == "" ]
then
  echo "grep \"^0$id,\" /var/www/acpog/upload/$st$sd* | cut -d',' -f 4-5 | tail -1"
  grep "^0$id," /var/www/acpog/upload/$st$sd* | cut -d',' -f 4-5 | tail -1
  dt=$(grep "^0$id," /var/www/acpog/upload/$st$sd* | cut -d',' -f 4-5 | tail -1)
fi

输出如下:

grep "^1419," /var/www/acpog/upload/0SCAN2013* | cut -d',' -f 4-5 | tail -1
grep "^1419," alt_upcs.csv | cut -d',' -f 2
9781844484201
," /var/www/acpog/upload/0SCAN2013* | cut -d',' -f 4-5 | tail -1
grep "^01419," /var/www/acpog/upload/0SCAN2013* | cut -d',' -f 4-5 | tail -1

第 1、2、3 和 5 行符合预期。第 4 行没有我试图回显的行的开头,直到逗号之前。如果我回显$j此行之后的变量,它会按预期包含 UPC,但使用该变量的 grep 命令也不会返回任何内容。

编辑:此外,上传目录中应该有 4 个文件匹配,所有文件都以0SCAN2013

以下是从提示符手动运行命令的一些进一步输出:

# echo "grep \"^$j,\" /var/www/acpog/upload/$st$sd* | cut -d',' -f 4-5 | tail -1"
grep "^9781844484201," /var/www/acpog/upload/0SCAN2013* | cut -d',' -f 4-5 | tail -1

# grep $j /var/www/acpog/upload/$st$sd*
/var/www/acpog/upload/0SCAN20130821213905:9781844484201,0,2,8:21,13:48:496

# grep $j /var/www/acpog/upload/$st$sd* | cut -d',' -f 1 | tail -1
/var/www/acpog/upload/4SCAN20130805204626:9781844484201

# grep $j /var/www/acpog/upload/$st$sd* | cut -d',' -f 2 | tail -1
2

# grep $j /var/www/acpog/upload/$st$sd* | cut -d',' -f 3 | tail -1
-1

# grep $j /var/www/acpog/upload/$st$sd* | cut -d',' -f 4-5 | tail -1
8:21,13:48:496

为了测试,这些文件应该可以工作。在脚本所在的目录中:文件名alt_upcs.csv包含 1 行:

1419,9781844484201

/var/www/acpog/upload/目录中,文件名0SCAN20130821213905包含1行:

9781844484201,0,2,8:21,13:48:496

答案1

您的 csv 文件有 Windows “CRLF” 行尾。(CR 是“回车符”,也写作\r\0x0D;LF 是“换行符”,\n\0x0A)。您使用的 unix 实用程序无法将 CR 识别为行尾的一部分,因此它成为查找的 UPC 的一部分。这将阻止找到 UPC。它还会产生误导性的输出(您的第 4 行),因为 CR 在输出时执行回车符,导致其后的回显部分(以 开头,")覆盖开头。

使用 dos2unix 或类似的实用程序来修复您的 csv 文件。

相关内容