AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 406738
Accepted
Santhosh Ram
Santhosh Ram
Asked: 2017-11-24 23:50:07 +0800 CST2017-11-24 23:50:07 +0800 CST 2017-11-24 23:50:07 +0800 CST

grep 从 $START 到 $END 的一组行并且在 $MIDDLE 中包含匹配项

  • 772

Grep/Awk/Sed 用于“0010|”中的一组行 到“0070|” 在 $PH_NO 中包含匹配项的 AND

下面是样本数据。我需要对 0012 字段中出现的电话号码和相应的完整客户记录进行 grep,从 0010 到 0070 行。一个数据文件可能包含两个或三个具有相同电话号码的客户记录,我需要获取所有这些记录。

0010|Kumar||57 Rich street|Chennai|Tamil Nadu|
0011|20171115| ID
0012|149 196 222| PH Number 
0013|20161101|20171102|
0022|Payment Method |Lucky customer|
0080|P|5.00-|20161111|Payment|
0080|P|5.00-|20161130|Payment|
0080|TP|10.00-|||
0070|000AYDCHDFF|820|762|
0010|RAM||57 Rich street|Chennai|Tamil Nadu|
0011|20171115| ID
0012|149 196 333| PH Number 
0013|20161101|20171102|
0022|Payment Method |Lucky customer|
0080|P|5.00-|20161111|Payment|
0080|P|5.00-|20161130|Payment|
0080|TP|10.00-|||
0070|000AYDCHDFF|820|762|
0010|Joe||57 Rich street|Chennai|Tamil Nadu|
0011|20171115| ID
0012|149 196 222| PH Number 
0013|20161101|20171102|
0022|Payment Method |Lucky customer|
0080|P|5.00-|20161111|Payment|
0080|P|5.00-|20161130|Payment|
0080|P|5.00-|20161111|Payment|
0080|P|5.00-|20161130|Payment|
0080|P|5.00-|20161111|Payment|
0080|P|5.00-|20161130|Payment|
0080|TP|10.00-|||
0070|000AYDCHDFF|820|762|

注意:我在带有 ksh 的 AIX 服务器上。

text-processing aix
  • 3 3 个回答
  • 655 Views

3 个回答

  • Voted
  1. Best Answer
    Philippos
    2017-11-25T03:16:13+08:002017-11-25T03:16:13+08:00

    所以你想要从 0010 到 0070 的整个记录​​,如果 PH 号码匹配$PH_NO"?然后这个sedoneliner 将起作用:

    sed "/^0010/,/^0070/H;/^0010/h;/^0070/! d;x;/|$PH_NO| PH Number/! d"
    
    • /^0010/,/^0070/H将一条从 0010 到 0070 的记录附加到保留空间
    • /^0010/h0010 不应该被附加,而是开始一个新记录,所以将它复制到保留空间
    • /^0070/! d除非是 0070 项目,否则不会进一步处理或输出
    • x;/|$PH_NO| PH Number/! d"交换空格,因此整个记录现在都在模式空间中,如果它不包含所述数字,则将其删除。
    • 3
  2. Bruce
    2017-11-25T00:56:18+08:002017-11-25T00:56:18+08:00
    for r in `grep -n '^0010\|^0012\|^0070' CUSTOMER_FILE | grep -C1 '[0-9]\+:0012|149 196 222|' | grep -o '^[0-9]\+' | paste -d, - - - | sed 's/,[0-9]\+,/,/g'`; do sed -n "$r"p CUSTOMER_FILE; echo; done
    

    149 196 222上面的命令是客户电话号码。将其更改为您要查找的电话号码。

    CUSTOMER_FILE是您要搜索的文件。将其更改为您的文件名。

    您还可以将代码放在 bash 脚本中,并替换149 196 222为$1和替换CUSTOMER_FILE为$2. 说find-customer.sh,然后你可以像这样执行脚本

    ./find-customer.sh '149 196 222' your-file-name

    这段代码的先决条件:

    1. Bash、GNU 环境(GNU grep、GNU sed)
    2. 您的文件必须遵循如下格式 0010 ... <no 0010 or 0012 or 0070> ... 0012 ... <no 0010 or 0012 or 0070> ... 0070 ... <repeated content as above or end of file>


    更新

    这是一个高性能版本。(至少比上面的原始更高。根本不涉及 for 循环。)

    grep -n '^0010\|^0012\|^0070' CUSTOMER_FILE | grep -C1 '[0-9]\+:0012|149 196 222|' | grep -o '^[0-9]\+' | paste -d, - - - | sed -r 's|([0-9]+),[0-9]+,([0-9]+)|\1,\2p;\2a|g' | sed -n -f - CUSTOMER_FILE
    


    AIX 更新

    由于提问者正在 AIX 上工作。AIX 上的 grep 不支持上下文选项 -A、-B、-C。

    在 Internet 上,有多种“cgrep”(上下文 grep)实现来解决这个问题(模拟 GNU grep 上下文选项)。但是它们中的大多数不能提供与 GNU grep 相同的输出。我发现只有一个最接近 GNU grep 上下文选项。链接是https://stackoverflow.com/questions/1685678/advanced-grep-unix/1685782#1685782

    我为这个案例做了一些必要的修改。

    #!/bin/bash
    BEFORE=$1
    AFTER=$1
    FILE=/tmp/.cattmp
    PATTERN="$2"
    cat > $FILE
    for i in $(grep -n "$PATTERN" $FILE | sed -e 's/\:.*//')
      do head -n $(($AFTER+$i)) $FILE | tail -n $(($AFTER+$BEFORE+1))
    done
    rm $FILE
    

    将此文件另存为并在我上面的命令中grep-context.sh替换grep -C1为。./grep-context.sh 1

    我认为一劳永逸的另一种方法是在 AIX 上编译 GNU grep。(也编译 GNU sed 以防万一)

    • 0
  3. Amir Amini
    2017-11-25T01:35:25+08:002017-11-25T01:35:25+08:00

    您可以使用此脚本:

    #!/bin/sh
    read START
    read END
    read MATCH
    
    REND=$(grep -n "$END" lines | tail -1 | cut -d":" -f 1)
    RSTART=$(grep -n "$START" lines | head -1 | cut -d":" -f 1)
    
    sed $RSTART,$REND!d lines | grep "$MATCH"
    

    将其放入文件并使用此命令添加执行权限

    chmod +x script.sh
    

    START 变量:您的起始行号(例如 0010)

    END 变量:您的结束变量(例如 0070)

    MATCH 变量:您在一行中查找的单词/字符/数字(例如 0012)

    RSTART 变量:文本文件中的起始行号(例如 1)

    REND 变量:文本文件中的起始行号(例如 32)


    编辑:

    您还可以通过将最后一行更改为以下内容来查看一行重复了多少次:

    sed $RSTART,$REND!d lines | grep "$MATCH" | sort | uniq -c
    
    • -1

相关问题

  • 重新排列字母并比较两个单词

  • 在awk中的两行之间减去相同的列

  • 多行文件洗牌

  • 如何更改字符大小写(从小到大,反之亦然)?同时[重复]

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    JSON数组使用jq来bash变量

    • 4 个回答
  • Marko Smith

    日期可以为 GMT 时区格式化当前时间吗?[复制]

    • 2 个回答
  • Marko Smith

    bash + 通过 bash 脚本从文件中读取变量和值

    • 4 个回答
  • Marko Smith

    如何复制目录并在同一命令中重命名它?

    • 4 个回答
  • Marko Smith

    ssh 连接。X11 连接因身份验证错误而被拒绝

    • 3 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Marko Smith

    systemctl 命令在 RHEL 6 中不起作用

    • 3 个回答
  • Marko Smith

    rsync 端口 22 和 873 使用

    • 2 个回答
  • Marko Smith

    以 100% 的利用率捕捉 /dev/loop -- 没有可用空间

    • 1 个回答
  • Marko Smith

    jq 打印子对象中所有的键和值

    • 2 个回答
  • Martin Hope
    EHerman JSON数组使用jq来bash变量 2017-12-31 14:50:58 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Drux 日期可以为 GMT 时区格式化当前时间吗?[复制] 2017-12-26 11:35:07 +0800 CST
  • Martin Hope
    AllisonC 如何复制目录并在同一命令中重命名它? 2017-12-22 05:28:06 +0800 CST
  • Martin Hope
    Steve “root”用户的文件权限如何工作? 2017-12-22 02:46:01 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST
  • Martin Hope
    Cbhihe 将默认编辑器更改为 vim for _ sudo systemctl edit [unit-file] _ 2017-12-03 10:11:38 +0800 CST
  • Martin Hope
    showkey 如何下载软件包而不是使用 apt-get 命令安装它? 2017-12-03 02:15:02 +0800 CST
  • Martin Hope
    youxiao 为什么目录 /home、/usr、/var 等都具有相同的 inode 编号 (2)? 2017-12-02 05:33:41 +0800 CST
  • Martin Hope
    user223600 gpg —list-keys 命令在将私钥导入全新安装后输出 uid [未知] 2017-11-26 18:26:02 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve