Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 调用';日期';awk字符串中的命令,带有+;%格式化_Bash_Shell_Date_Awk - Fatal编程技术网

Bash 调用';日期';awk字符串中的命令,带有+;%格式化

Bash 调用';日期';awk字符串中的命令,带有+;%格式化,bash,shell,date,awk,Bash,Shell,Date,Awk,对这个网站来说还是新的,但这里是。。。 基本上,我将事件存储在多个文件中,每个事件都是一行,每行包含日期($1)、开始($2)和停止($3)时间以及其他几段数据。我使用两个双下划线(“_;”)作为字段分隔符。我一直在使用各种shell脚本来管理数据,我在使用awk来计算统计数据,我在调用date函数时遇到了问题,因此我无法获得一周中每一天的总数。在对讨论板进行了大量修补和扫描后,我得出了以下结论: ls /home/specified/folder/MBRS.db/* | xargs -n 1

对这个网站来说还是新的,但这里是。。。 基本上,我将事件存储在多个文件中,每个事件都是一行,每行包含日期($1)、开始($2)和停止($3)时间以及其他几段数据。我使用两个双下划线(“_;”)作为字段分隔符。我一直在使用各种shell脚本来管理数据,我在使用awk来计算统计数据,我在调用date函数时遇到了问题,因此我无法获得一周中每一天的总数。在对讨论板进行了大量修补和扫描后,我得出了以下结论:

ls /home/specified/folder/MBRS.db/* |
xargs -n 1 -I % awk -F"__" '$6 == "CLOSED" && $1 >= "'$backDATE'" { print $0 }' % |
awk 'BEGIN{FS="__"}{specDATE=system("date --date="$1" +%a")} specDATE == "Tue" {print $2" "$3}'

我没有输出开始和停止时间,而是为每个条目获取一周中所有不同日期的列表

我尝试了比我愿意承认的更多的日期用法变体,包括:

for y in Sun Mon Tue Wed Thu Fri Sat; do
  for directory in $( ls /home/specified/directory/MBRS.db/* | xargs -n 1 ); do
    printf "."
    [[ $( cat $directory | awk -F"__" '$6 == "CLOSED" && $1 >= "'$backDATE'" { print $1 }' | xargs -n 1 -I z date +%a -d z ) == "$y" ]] && echo BLAH
  done
done

如果能对我搞砸的事情做出一些有益的解释,我将不胜感激。提前谢谢。哦,我正在以YYMMDD格式存储日期,但对于ubuntu服务器版本的“日期”来说,这似乎不是一个问题。

好的,所以我最后使用了这个:

>backDATE=150000; 
>     for x in $listOFsites; do
>        for y in Sun Mon Tue Wed Thu Fri Sat; do
>            totalHOURS=$( awk 'BEGIN{FS="__"} NF == 10 && $1 >= "'$backDATE'" && $4 == "'$x'" && $6 == "CLOSED" {while ( ( "date +%a -d \""$1"\"" | getline newDAY) > 0 ){if (newDAY == "'$y'") print $2" "$3}}' /home/absolute/path/* | xargs -I % /home/custom/duration/calc % | paste -sd+ | bc ); printf "."; 
>        done
>     done

我不得不在单引号内使用date(这样我就可以将$1传递给它),而不是在单引号外使用date(使用-F“\uuuv”-newDAY=…),但是在单引号内获取system()的输出是有问题的。看了之后:我终于看到了while(cmd | get line x)格式,这是我问题的关键。埃德·莫顿的道具

我不知道它的其余部分(对我的阅读品味来说,文本太多了!),但请写出你发布的答案,这部分:

awk 'BEGIN{FS="__"} NF == 10 && $1 >= "'$backDATE'" && $4 == "'$x'" && $6 == "CLOSED" {while ( "date +%a -d "$1"" | getline newDAY){if (newDAY == "'$y'") print $2" "$3}}' /home/absolute/path/*
假设它符合您的要求,则会写成:

awk -v backDATE="$backDATE" -v x="$x" -v y="$y" '
    BEGIN { FS="__" }
    (NF == 10) && ($1 >= backDATE) && ($4 == x) && ($6 == "CLOSED") {
        cmd = "date +%a -d \"" $1 "\""
        while ( (cmd | getline newDAY) > 0 ) {
            if (newDAY == y) {
                print $2, $3
            }
        }
        close(cmd)
    }
' /home/absolute/path/*
wrt为什么使用awk变量而不是让shell变量扩展成为shell脚本主体的一部分,答案是健壮性和简单性

这是让shell变量展开成为awk脚本主体的一部分:

$ x="hello world"
$ awk 'BEGIN{ print '$x' }'
awk: cmd. line:1: BEGIN{ print hello
awk: cmd. line:1:                   ^ unexpected newline or end of string
$ awk 'BEGIN{ print "'$x'" }'
awk: cmd. line:1: BEGIN{ print "hello
awk: cmd. line:1:              ^ unterminated string
awk: cmd. line:1: BEGIN{ print "hello
awk: cmd. line:1:              ^ syntax error
$ awk 'BEGIN{ print "'"$x"'" }'
hello world
$ x="hello
world"
$ awk 'BEGIN{ print "'"$x"'" }'
awk: cmd. line:1: BEGIN{ print "hello
awk: cmd. line:1:              ^ unterminated string
awk: cmd. line:1: BEGIN{ print "hello
awk: cmd. line:1:              ^ syntax error
这是使用一个用shell变量值初始化的awk变量:

$ x="hello world"
$ awk -v x="$x" 'BEGIN{ print x }'
hello world

$ x="hello
world"
$ awk -v x="$x" 'BEGIN{ print x }'
hello
world
看到区别了吗

至于为什么要将命令存储在一个变量中,因为在使用它之后必须关闭它,而且它在close命令中的拼写方式必须与打开管道时完全相同。比较:

cmd = "date +%a -d \"" $1 "\""
cmd | getline
close(cmd)
vs:


然后用一个非常接近的第二个look来发现第二个版本中的错误。

我认为您需要避开
{specDATE=system(“date--date=“$1”+%a”)}
中嵌套的双引号,如下所示:
{specDATE=system(“date--date date=\“$1\+%a”)}
。至少,我会对这段语法保持警惕,因为当shell看到
$1
时,它在引号之外。我认为您应该使用能更直接地管理日期的
awk
以外的语言编写代码<代码>awk很棒-别误会我的意思。但是,每行数据运行一次
date
对性能没有好处。我会使用Perl(但我已经使用Perl二十年了);使用Python可能更明智。我认为
xargs
命令中的
-n1
-I%
(以及随后的
%
)只是减慢处理速度的方法
awk
可以愉快地处理多个文件。在两个
awk
脚本中,将字段分隔符设置为
\uuuu
的不对称方式很奇怪。第二个脚本应该与第一个脚本相结合,因此您只运行一个
awk
脚本。允许在多行上放置
awk
脚本。通常明智的做法是将每个
模式{action}
单元放在自己的行上,除非所有内容都适合放在一行上。如果
{action}
本身需要多行代码,请使用它们。我最初只使用一个awk程序,但由于存在问题,我使用管道和XARG尝试分离出我正在执行的操作以查看错误。例如,当我使用以下内容时,我可以打印出一周中的某一天,但我在使用它进行任何类型的条件检查(即,这是星期二)时遇到了困难:ls/home/absolute/path/*|xargs-n1-I%awk-F”“'$6==“CLOSED”&&$1>=“$backDATE”“{print$0}'''''/| awk'BEGIN{FS=”“}$4='SJ{system(“date d”$1+%a”)'awk-F''-v newDAY=“date-d”$1+%a”$6==“CLOSED”&$1>=“'150000'{print newDAY}'/home/lingotech/Einstein/data/MBRS.db/*..类似的示例将newDAY作为字符串“date-d”$1+%a”传递,但如果您使用Ubuntu,我希望它运行date命令并存储其值,
gawk
strftime
可以简化事情。当前的
mawk
(与Ubuntu中的版本不同)也支持
strftime
。别怪我:-)-这不是编写命令的方式!在日期段中添加了\“during”并调整了while语句,但它的执行方式仍然相同。如果您能稍微解释一下“为什么”,它将真正帮助我理解我做错了什么。仅仅使用发布的代码就有点让我这么做:)我将回溯日期、x和y设置在awk程序之外(并在其他地方使用它们),那么使用-v而不是使用“$x”有什么好处呢“要展开变量吗?还想知道关于使用cmd变量而不是仅仅在condition语句中编写命令的相同内容吗?我不想说得太具体,但我只是想弄清楚一种方法对awk阅读是否更有效,或者对人类来说是否更容易,等等……我只是编辑了我的答案,添加了为什么要使用变量以及为什么要使用cmd变量的解释。谢谢,这完全澄清了问题。使用-v来创建特定于awk的变量版本肯定会节省我无数时间来查找恶意引号,感谢您继续解释。另外,我之前完全错过了close(),再次感谢!
cmd = "date +%a -d \"" $1 "\""
cmd | getline
close(cmd)
"date +%a -d \"" $1 "\"" | getline
close("date +%a -d \"" $l "\"")