【问题标题】:ksh string manipulation $#@!?ksh 字符串操作 $#@!?
【发布时间】:2011-08-13 06:51:10
【问题描述】:

所以我有这个具有这种内容的假脱机文件。

SQL> select file_name from dev_files;

FILE_NAME
------------------------------------------------------------------
file1.txt
file2.doc
file3.pdf
total.xls

4 rows selected.

SQL> spool off

我正在编写一个 ksh 脚本来将这些文件加载​​到 ftp 服务器并更新日志文件。我被卡住了。这是我多次尝试后糟糕的代码部分。

dump="spoolfile.txt"

while read line;
do

if [[`expr match "$line" 'SQL'` !=3]] && [[`expr match "$line" 'FILE_NAME'` !=9]] && [[`expr match "$line" '---------'` !=9]]
then
    ftp -inv $tgt_server <<EOT
    quote user $uname
    quote password $pword
    mput $src_path/$line
    quit
    EOT

    echo "sent $line" >> sent_files.log
fi
done < $dump

我如何确保“没有选择行”并说“选择了 4 行”。没读过?可以有任何数字而不是 4 对应于文件的数量。在没有文件的情况下,假脱机文件看起来像这样。这 '。'也不见了。

SQL> select file_name from dev_files;

no rows selected

SQL> spool off

【问题讨论】:

  • 您是否可以控制生成 spoolfile.txt 的 SQL*Plus 脚本?如果是这样,您可以事先过滤掉这些行。
  • 是的,我想到了。但似乎另一个日志文件需要输出。
  • 嗯,这将是最简单的,您可以在之后添加所需的日志记录:set heading off set feedback off set pagesize 0 set echo off
  • 这些假脱机文件是在别处生成的,所以我可能无法更改它们。有更好的解决方案吗?我已经邮寄了可以访问这些脚本的人。但最坏的情况呢?

标签: shell string ftp ksh


【解决方案1】:

我同意大多数关于 SQLPlus 中“关闭标题”等的 cmets,

但这很简单;-)

while read line;
do
   case ${line} in 
     -------* ) continue ;;
     FILE_NAME ) continue ;;
     SQL[>] ) continue ;;
     *rows\ selected ) continue ;;
   esac 

   # with enough case match targets, you can probably eliminate
   # the if/fi completely. Good luck.
   if [[`expr match "$line" 'SQL'` !=3]] .....
   ftp ...
   fi
done < $dump

您必须尝试在 case 语句中放入什么值才能彻底清除它。

还请注意,对于任何不寻常的字符,例如“>”,最好将它们作为字符类包含在 [&gt;] 中(同样需要您进行一些实验)

最后,请注意,如果您想在大小写匹配目标中包含空白字符,请在 dbl-quotes (") 中将短语括起来或转义每个 WS 字符,如 '\'。

【讨论】:

  • hhaha.. 首先,我不是 shell 专家,实际上我期待某种正则表达式的答案,而且我已经有一段时间登录了 stackoverflow.. ;) 也不会搜索“selected”帮助,因为它可以是文件名
  • 如果您希望得到一个正则表达式的答案,您应该在您的问题或标签中指出这一点。但是,无需防御,只需对您收到的一些对您有帮助的答案进行投票即可。 *** 在任何情况下 ***,Case 语句按设计使用正则表达式作为匹配目标。仅仅因为我在这个例子中没有使用正则表达式的全部功能并不意味着它们不能。当每种情况都明确时,更容易理解代码。我将稍微扩展我的答案以表示诚意,并向您展示案例陈述可以使用reg exp。
【解决方案2】:

这是一个更简单的解决方案:与其尝试查找要忽略的行,不如标记要处理的行:

select concat("JHFDGFSH ",file_name) from dev_files

现在您需要做的就是忽略任何不以JHFDGFSH 开头的行。

[编辑] 如果您不能这样做:当您遇到只有---- 的行时开始阅读,并在第一个空行处停止。除非 Oracle 开始分页,否则这应该可以工作。

并为上游打开一个问题,告诉他们他们的界面很脆弱并且它最终会崩溃。

如果没问题,那不是你的问题,也不是你的错,因为它发生了故障并且生产中断了几天;只需显示问题并说“看到了吗?你想要这样。”

KSH 也可能不是正确的工具;看看awk。这应该有效:

/^---+/,/^[ \t]*$/ { print; }

如果你不能使用awk,如何将每一行都当作一个文件名,忽略那些不存在的?

只要没有人创建名为FILE_NAME4 rows selected.SQL&gt; spool off 的文件,只要确保正确引用所有字符串,就应该可以找到您。

【讨论】:

  • 这是一个很好的解决方法,但我想我无法更改查询的工作方式,因为我是生成假脱机文件后出现的界面的一部分
  • 最后一行+1 :)。希望他们改变标题并回显
猜你喜欢
  • 2011-05-12
  • 1970-01-01
  • 2012-10-15
  • 2017-03-22
  • 2018-06-28
  • 1970-01-01
相关资源
最近更新 更多