在awk字符串中调用'date'命令,格式为+%

时间:2015-03-23 04:05:37

标签: bash shell date awk

该网站仍然新鲜,但这里...... 基本上我将事件存储在多个文件中,每个事件都是一行,每行包含日期($ 1),开始($ 2)和停止($ 3)次以及其他几个数据。我使用两个双下划线(" __")作为字段分隔符。我一直在使用各种shell脚本来管理数据,我使用awk来计算统计数据,而且我在调用日期函数时遇到问题,因此我可以在一周中得到总数。经过大量的修补和扫描讨论板后,我得到了这个:

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}'

ls /home/lingotech/Einstein/data/MBRS.db/* |
xargs -n 1 -I % awk -F"__" '$6 == "CLOSED" && $1 >= "'$backDATE'" { print $0 }' % |
awk 'BEGIN{FS="__"}system("date --date="$1" +%a") == "Mon" {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服务器版本的“约会”而言,这似乎不是问题。

2 个答案:

答案 0 :(得分:0)

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

>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

我不得不在单引号内使用日期(以便我可以将$ 1传递给它)而不是在外面(使用-F“__”-v newDAY = ...),但在单引号内获取输出system()是有问题的。看到后:How can I pass variables from awk to a shell command?我终于看到了while(cmd | get line x)格式,这是我的问题的症结所在。 Ed Morton的道具

答案 1 :(得分:0)

我不知道其余的所有内容(我的阅读口味太多了!)但是你发布的答案是这个部分:

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/*

为什么使用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

"date +%a -d \"" $1 "\"" | getline
close("date +%a -d \"" $l "\"")

并采取非常接近的第二个 l 来发现第二个版本中的错误。