【问题标题】:Using wildcard character in bash scripting在 bash 脚本中使用通配符
【发布时间】:2011-11-08 04:52:00
【问题描述】:

我正在创建一个 bash 脚本,它将使用 SQL*Loader 加载 CSV 文件。请参考以下代码:

#!/bin/bash
FILENAME = '/u02/logs/$(date -d '2 days ago' +%Y-%m-%d)*.csv'

# LOAD CSV FILE USING SQL*LOADER
sqlldr username/password@localhost control=control.ctl data=$FILENAME

但是,当我尝试运行此脚本时,我收到以下错误:SQL*Loader-500: 无法打开文件 (/u02/logs/*2011-11-06*.csv)。我发现问题是我的 * 通配符在 bash 中被解释为字符串而不是通配符。

有没有办法告诉 bash 我的星号 (*) 是通配符而不是字符串?

感谢您的支持。

【问题讨论】:

  • 您的 $FILENAME 正在使用单个刻度。没试过,但你试过用双引号代替吗?
  • 是的。事实上,我可以回显完整的 $FILENAME。但是当我把它放在我的 SQL*Loader 中时,它根本就不起作用。
  • 您会发现解决方案比您预期的要难。

标签: database linux bash unix sql-loader


【解决方案1】:

我不知道sqlldr,但我想你可以试试:

#!/bin/bash
FILENAME = '/u02/logs/$(date -d '2 days ago' +%Y-%m-%d)*.csv'

# LOAD CSV FILE USING SQL*LOADER
for fname in $(ls $FILENAME); do
    sqlldr username/password@localhost control=control.ctl data=$fname
done

希望对你有帮助

【讨论】:

  • 你的代码就像一个魅力!我想知道为什么我不能像在 echo 中那样将文件传递给 SQL*Loader。无论如何,非常感谢! :-)
  • @user692533:echo 没有向您展示您的想法。比较运行echo "$FILENAME"echo $FILENAMEecho data=$FILENAME 的结果。第一个向您展示了 FILENAME 变量中的实际内容,包括文字星号。第二,shell 在将参数传递给echo 之前进行文件名匹配,因此您会看到匹配的文件名而不是星号。在最后一种情况下,shell 认为“data=”是它应该寻找的文件名的一部分,没有找到任何匹配的东西,所以它留下了文字星号。
  • @Gordon Davisson 感谢您告诉我 :-)
【解决方案2】:

您对单个刻度的使用是问题所在。另外,我不习惯看到 bash 代码在等号周围有空格。再说一次,我是老派。所以这就是我要做的:

FILENAME=/u02/logs/"$(date -d '2 days ago' +%Y-%m-%d)*.csv"

应该这样做。您不需要在第一部分加上引号,因为它们是字面的。仅当您需要解释器进行插值时才使用双引号。当您不希望解释器触摸它时,请使用单引号。

【讨论】:

  • 然后,您可以在等号之后立即开始双引号。这真的只是风格问题。
  • 我试过你的代码。我什至删除了等号中的空格。当我使用 echo 显示变量 FILENAME 的值时,它会显示正确的“/u02/logs/2011-10-05_other_values.csv”。但 sqlloader 仍将其解释为 'u02/logs/2011/10/05.csv'。顺便说一下,我用的是Redhat linux
  • 谢谢史蒂夫。但是 SQL*Loader 仍然将我的 *(星号)解释为字符串而不是通配符
  • 它正在寻找匹配 data=u02/logs/2011/10/05*.csv 的文件,即它认为“data=”是文件名的一部分。如果 sqlldr 允许,在data= 之后放置一个空格会起作用。或者,尝试FILENAME_ARRAY=($FILENAME),然后尝试sqlldr ... data="${FILENAME_ARRAY[@]}"
  • 嗯,/u02/logs/2011-10-05_other_values.csv(我的 bash 语句的结果)与 u02/logs/2011/10/05*.csv(缺少前导斜杠字符是第一个死赠品)不同。在创建 FILENAME 之后,您是否对其进行了不同的处理?
【解决方案3】:

随便用

FILE=/u02/logs/$(date -d '2 days ago' +%Y-%m-%d)*.csv

我还注意到错误消息中logs/ 之后的附加*,但在您的代码中没有。相应调整。 如果没有与通配符模式匹配的文件,* 将保留在文件名中。此外,请注意存在多个匹配文件的情况。

【讨论】:

  • 哇,你真的是一个很好的调试器朋友!我尝试删除单个 qoutations。它仍然无法正常工作。无论如何谢谢:-)
【解决方案4】:

也许你可以试试:

sqlldr username/password@localhost control=control.ctl data="$FILENAME" 

【讨论】:

  • 谢谢哥们!我尝试了双引号,但 SQL*Loader 仍将其解释为字符串。 :-(
猜你喜欢
  • 1970-01-01
  • 2021-03-13
  • 1970-01-01
  • 2015-05-04
  • 1970-01-01
  • 2021-06-01
  • 2013-11-14
  • 2012-10-14
  • 1970-01-01
相关资源
最近更新 更多