我的目录中有一组文件。每个文件都会有一行名为---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_NO
is 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
字符串,前面加上该字符串所在的文件名。