【问题标题】:in awk facing issues while using variable as search pattern while searching in a file在 awk 中,在文件中搜索时使用变量作为搜索模式时面临问题
【发布时间】:2016-01-04 17:39:52
【问题描述】:
date;
tocompdate=$(date --date="-90 days ago" +%d%m%Y)
echo $tocompdate;

awk -v pattern="$testdate" '{print "Some matter "nr[NR--]" matter "$testdate""};' tocompare.txt >> mail2sent.txt`

在这里,我取当前日期并将其添加 90 天并将其存储在 tocompdate 中。并将tocompdate 与一个文件进行比较,其中同一行中存在相同的日期,而该行之前的其他行中存在一些其他问题。

当搜索模式匹配时,我需要打印一些文本并打印“匹配行之前的行”,然后在几个单词后再次匹配行。

例如:

文件有以下内容

a1
28112019
b2
04032018
c3
04032018
d4
27072015
e5
27072015
f6
06012030

如果我与27072015 进行比较,我希望输出如下

The d4 is on 27072015
The e5 is on 27072015

【问题讨论】:

  • 这里的问题到底是什么?如何使用pattern作为匹配的模式?
  • 是 ...匹配文件中的模式并在匹配字符串与匹配字符串之前打印一行

标签: bash file shell design-patterns awk


【解决方案1】:
$ awk -v tgt="27072015" '$0==tgt{printf "The %s is on %s\n", p, $0} {p=$0}' file
The d4 is on 27072015
The e5 is on 27072015

【讨论】:

  • 谢谢。发明 shell 来操作文件和进程以及对工具的调用排序的人,还发明了 awk 作为 shell 调用来操作文本文件的工具,所以它只是课程的马......如果你将在 UNIX 中进行任何文本操作,我强烈推荐 Arnold Robbins 的《Effective Awk Programming, 4th Edition》一书。
【解决方案2】:

只是为了好玩:使用sedgrepxargs 的另一种解决方案

xargs -n 2 <file | grep -E '\b27072015$' | sed -r 's/^(\S+)\s(\S+)$/The \1 is on \2/g'

你明白了,

d4 在 27072015 e5 在 27072015

【讨论】:

    【解决方案3】:

    我提出一个只使用 shell 编程的解决方案:

    #!/bin/sh 
    
    match="27072015"
    
    while IFS= read -r i
    do if [ "$i" = "$match" ]
       then printf "The %s is on %s\n" "$last" "$match"
       fi
       # test that we are not in a whitespace
       if [ -n "$i" ]
       then last="$i"
       fi
    done < tocompare.txt
    

    注意:此解决方案仅适用于没有特殊字符的非常小且简单的数据集。此外,它比使用awk 慢得多。

    【讨论】:

    • 取决于compare.txt 的内容,这会在输出时损坏它。对于大文件,它也会非常慢。使用 shell 循环总是错误的方法,请参阅unix.stackexchange.com/questions/169716/…。并且不要按照约定对未导出的变量名称使用全大写,以避免与 HOME、PATH、IFS 等内置名称发生冲突。
    • I如果文件包含a\tb,那么while read i 将使用atb 填充i,因为read 默认情况下会进行转义。它对空格也有意想不到的效果。任何时候您编写一个 shell 循环来从未更改的文件中读取行时,您都需要编写 while IFS= read -r i,除非您有特定的任务并且完全理解不这样做的所有注意事项。为什么 shell 会这样?因为,与不带引号的变量一样,shell 不适用于操作文本,因此它的默认行为在某些适合 shell 的上下文中有意义,但不适用于操作文本。
    猜你喜欢
    • 2016-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    • 2019-01-17
    • 1970-01-01
    相关资源
    最近更新 更多