GREP 查找模式并删除模式之前或之后的所有垃圾字符

GREP 查找模式并删除模式之前或之后的所有垃圾字符

我的目录中有一组文件。每个文件都会有一行名为---PUBG-xxxxx--or 的行---PUBG-xxxxx, PUBG-yyyyy ----。以下是 grep 命令的输出。

grep "^--" FILE*.sql | grep "PUBG"

FILE1.sql:---PUBG-10901--
FILE2.sql:---PUBG-11617--
FILE3.sql:---PUBG-11625--
FILE4.sql:--PUBG-11724--
FILE5.sql:---PUBG-11720, PUBG-11406---
FILE6.sql:---PUBG-11403---
FILE7.sql:---PUBG-12021--
FILE8.sql:---PUBG-12207--
FILE9.sql:---PUBG-12270--
FILE10.sql:---PUBG-12552--
FILE11.sql:--- PUBG-14284--
FILE12.sql:--- PUBG-10908--
FILE13.sql:--- PUBG-15136---
FILE14.sql:--- PUBG-15163---
FILE15.sql:--- PUBG-15166---
FILE16.sql:-- PUBG-15059 --
FILE17.sql:-- PUBG-15252 --

PUBG 及其编号将是随机的。我需要的只是文件名及其关联的 PUBG 值,而不需要任何--前后的 PUBG 及其值。也可以有多个 PUBG,如FILE5.sql:---PUBG-11720, PUBG-11406---.我写了下面的 for 循环集。

for (i in `grep "^--" FILE*.sql | grep "PUBG"`)
do
    FILE_NAME=`echo ${i} |  awk -F ":" {'print $1'}`
    PUBG_NO=`echo ${i} | awk -F "PUBG-" {'print "PUBG-" $2'}`
    echo ${FILE_NAME}
    echo ${PUBG_NO}
done

但 的样本输出PUBG_NOis PUBG-15166---forFILE15.sql 和 is PUBG-11720,for FILE5.sql

我需要一个文件中特定 FILE_NAME 的所有 PUBG 值,而不需要任何--. FILE5.sql 的 PUBG 值可以是PUBG-11720, PUBG-11406如何改进此循环以获取准确的结果。

答案1

您不需要编写循环。您可以将输出通过管道传输到 sed 。我的尝试如下:

grep "^--" FILE*.sql | grep "PUBG" | sed -E 's/--+\ ?//g'

这会给

FILE1.sql:PUBG-10901
FILE2.sql:PUBG-11617
FILE3.sql:PUBG-11625
FILE4.sql:PUBG-11724
FILE5.sql:PUBG-11720, PUBG-11406
FILE6.sql:PUBG-11403
FILE7.sql:PUBG-12021
FILE8.sql:PUBG-12207
FILE9.sql:PUBG-12270
FILE10.sql:PUBG-12552
FILE11.sql:PUBG-14284
FILE12.sql:PUBG-10908
FILE13.sql:PUBG-15136
FILE14.sql:PUBG-15163
FILE15.sql:PUBG-15166
FILE16.sql:PUBG-15059 
FILE17.sql:PUBG-15252 
FILE14.sql:PUBG-15163
FILE15.sql:PUBG-15166
FILE16.sql:PUBG-15059 
FILE17.sql:PUBG-15252 

在这里,我使用 sed substitue 命令,其形式为

's/regular expression/substition/flag'

进一步分解该命令:

  • 正则表达式“--+\?”是您要查找和选择的模式。这可以理解为“查找一个模式,其中“-”后跟一个或多个连续的“-”,后跟零个或一个“”。这将匹配“--”、“---”和“-” -- " 在你的输出中。请注意,你需要 sed 的 -E 标志才能识别这些量词。这是复习正则表达式量词的快速参考,例如 ?和+
  • 这里,替换空间留空。这会将找到的模式替换为空,并且是剥离输出的有效方法。
  • 标志“g”表示搜索将是全局的。如果没有这个,替换只会发生在每行的第一场比赛中。添加 g 将确保每行上该模式的每个实例都被替换为任何内容。

您还可以将这些概念应用到初始 grep 命令中以仅执行一次搜索。

grep -E "^--+\ ?PUBG" FILE*.sql | sed -E 's/--+\ ?//g'

答案2

以下 AWK:

awk '
BEGIN { RS="[,\n]"; }
/PUBG-[0-9][0-9][0-9][0-9][0-9]/ { match($0,/PUBG-[0-9][0-9][0-9][0-9][0-9]/); print(FILENAME ":" substr($0,RSTART,RLENGTH)); }
' FILE*.sql

将给出以下输出:

FILE11.sql:PUBG-14284
FILE1.sql:PUBG-10901
FILE3.sql:PUBG-11625
FILE5.sql:PUBG-11720
FILE5.sql:PUBG-11406

仅考虑 5 个文件:

$ ls FILE*.sql
FILE11.sql  FILE1.sql  FILE3.sql  FILE5.sql

答案3

awk -F, '/^--/ && /PUBG/ {
    for (i=1; i<=NF; ++i) {
        sub("^[- ]*", "", $i)
        sub("[- ]*$", "", $i)
        print FILENAME, $i
    } }' FILE*.sql

这将遍历原始 SQL 文件并替换您的管道。

awk代码提取所有以 开头--且包含字符串 的行PUBG。对于每个这样的行,它会遍历以逗号分隔的条目,并从每个条目的开头和结尾去除任何破折号和空格字符。修剪后,它会打印结果PUBG-NNNN字符串,前面加上该字符串所在的文件名。

相关内容