Regex 隐藏cat提示错误

Regex 隐藏cat提示错误,regex,linux,bash,shell,cat,Regex,Linux,Bash,Shell,Cat,我想设置一个脚本,以便连续解析xml文件中的特定标记 脚本包含以下while循环: function scan_t() { INPUT_FILE=${1} while : ; do if [[ -f "$INPUT_FILE" ]] then ret=`cat ${INPUT_FILE} | grep "<data>" | awk -F"=|>" '{print $2}' | awk -F"=|<" '{print $1}'` if [

我想设置一个脚本,以便连续解析xml文件中的特定标记

脚本包含以下
while
循环:

function scan_t()
{
INPUT_FILE=${1}
while : ; do
   if [[ -f "$INPUT_FILE" ]]
   then
      ret=`cat ${INPUT_FILE} | grep "<data>" | awk -F"=|>" '{print $2}' | awk -F"=|<" '{print $1}'`
      if [[ "$ret" -ne 0 ]] && [[ -n "$ret" ]]
      then
         ...
      fi
   fi
done
} 
scant_t "/tmp/test.xml"
功能扫描
{
输入文件=${1}
当:;做
如果[-f“$INPUT_文件”]]
然后

ret=`cat${INPUT_FILE}| grep”“| awk-F”“=|>“{print$2}”| awk-F”“=|如果其他进程也可以在脚本看到该文件之前读取并删除该文件,那么您的系统就设计了一个争用条件(我假设“charged to suppress”意味着“设计为取消链接”)

如果此脚本可以选择查看每个输入文件,则只需将stderr重定向到
/dev/null
(即,当竞争条件生效时忽略错误)。如果不是可选的,则让此脚本将输入文件重命名为其他文件,并让其他进程监视该文件。在重命名之前,请检查该文件是否存在,以确保不会覆盖其他进程尚未读取的文件


你的循环有一个糟糕的设计。首先,你正忙着等待(根本没有
睡眠
)文件的出现。其次,当输入存在时,你正在运行4个程序,而不是1个

通过使用
inotifywait
监视目录的更改,可以避免繁忙的等待。因此
if[[-f$INPUT\u FILE]]
循环体仅在修改目录后运行,而不是以CPU核心可以运行的速度运行


第二个更容易处理:永远不要
cat file | something
。如果
something
命令行上没有文件名,或者行为不同,则
cat
只有在有多个文件要连接时才有用。用于将文件读入Shelll变量,使用
foo=$(如果其他进程也可以在脚本看到该文件之前读取并删除该文件,那么您的系统就设计了一个竞争条件。(我假设“充电以抑制”表示“设计为取消链接”。)

如果此脚本可以选择查看每个输入文件,则只需将stderr重定向到
/dev/null
(即,当竞争条件生效时忽略错误)。如果不是可选的,则让此脚本将输入文件重命名为其他文件,并让其他进程监视该文件。在重命名之前,请检查该文件是否存在,以确保不会覆盖其他进程尚未读取的文件


你的循环有一个糟糕的设计。首先,你正忙着等待(根本没有
睡眠
)文件的出现。其次,当输入存在时,你正在运行4个程序,而不是1个

通过使用
inotifywait
监视目录的更改,可以避免繁忙的等待。因此
if[[-f$INPUT\u FILE]]
循环体仅在修改目录后运行,而不是以CPU核心可以运行的速度运行



第二个更容易处理:永远不要
cat file | something
。如果
something
命令行上没有文件名,或者行为不同,则
cat
只有在有多个文件要连接时才有用。用于将文件读入Shelll变量,使用
foo=$(这很奇怪,可能是一种竞争条件。要隐藏此类错误,您可以将
stderr
重定向到
/dev/null
-->
cat文件2>/dev/null
。此外,您不是说
cat文件| grep | awk | awk
。可能一个简单的
awk'.'文件就足够了。谢谢您的建议,我已经用
c>进行了交流。)在文件| awk-F'[]'/data/{printf”%s“,$3}END{print”“}
Nice!注意
cat文件| awk'…'
可以更好地写成
awk'…'文件
。你试过添加这样的引号吗?:
cat“${INPUT\u file}”
注释:要回复用户,请使用
符号(例如:@SnP)这很奇怪,可能是一种竞争条件。要隐藏此类错误,您可以将
stderr
重定向到
/dev/null
-->
cat文件2>/dev/null
。另外,您不是说
cat文件| grep | awk | awk
。可能一个简单的
awk'.'文件就足够了。谢谢您的建议,我已经使用
ca>进行了交流t file | awk-F'[]'/data/{printf”%s',$3}END{print'}'
Nice!注意
cat file | awk'.'
可以更好地写成
awk'.''''.
文件。你试过添加这样的引号吗?:
cat“${INPUT\u file}”
注释:要回复用户,请使用
符号(例如:@SnP)重写显然是一个实质性的改进,但您可能会注意到,使用
cat
不仅仅是;如果您使用
grep
直接读取文件,您可以简单地使用
-s
来抑制错误消息。感谢Peter提供这些信息,这非常有趣!!但我应该提到我是wo在嵌入式平台上运行rking,其发行版是使用Yocto创建的。inotify tools包目前未包含在文件系统中。由于该包未定义为poky或meta oe层,因此我无法添加它,即使我知道如何添加。此外,您还说,
”然后让此脚本将输入文件重命名为其他文件“
”,并在重命名之前检查该文件是否存在“
。如果在[[-f”$input\u file]]之后执行
mv
提示错误只会被交换到
mv:没有这样的文件或目录
,不是吗?@SnP:如果
$INPUT\u File
的另一个使用者正在等待另一个名称,它不会从该脚本中窃取输入文件。不需要重定向
mv
的stderr来丢弃错误消息。@SnP:custom build inotifywait用于您的嵌入式平台,或者使用来自perl的inotify系统调用(或者您已经使用的其他语言)
<data>0</data> or <data>1</data> <data>2</data> ..
INPUT_FILE=foo;
inotifywait -m -e close_write -e moved_to --format %f . |
while IFS= read -r event_file;do
    [[ $event_file == $INPUT_FILE ]] &&
       awk -F '[<,>]' '/data/ {printf "%s ",$3} END {print ""}' "$INPUT_FILE" 2>/dev/null

     #  echo "$event_file" &&
     #  date;
done
# tested and working with the commented-out echo/date commands
# Race condition with an asynchronous producer, DON'T USE
while inotifywait -qq -e close_write -e moved_to; do
    [[ $event_file == $INPUT_FILE ]] &&
       awk -F '[<,>]' '/data/ {printf "%s ",$3} END {print ""}' "$INPUT_FILE" 2>/dev/null
done
#include <unistd.h>    // for usleep/dup2

#include <sys/types.h>  // for open
#include <sys/stat.h>
#include <fcntl.h>

#include <errno.h>
#include <stdio.h>  // for perror

void waitloop(const char *path)
{
    const char *const awk_args[] = { "-F", "[<,>]",
         "/data/ {printf \"%s \",$3} END {print \"\"}",
         path
    };
    while(42) {
        int fd = open(path, O_RDONLY);
        if (-1 != fd) {
            // if you fork() here, you can avoid the shell loop too.

            dup2(fd, 0);  // redirect stdin from fd.  In theory should check for error here, too.
            close(fd);   // and do this in the parent after fork
            execv("/usr/bin/awk", (char * const*)awk_args);  // execv's prototype doesn't prevent it from modifying the strings?
        } else if(errno != ENOENT) {
            perror("opening the file");
        } // else ignore ENOENT
        usleep(10000);  // 10 milliseconds.
    }

}
// optional TODO: error-check *all* the system calls.