我是bash的新手,正在尝试从文件中提取模式列表:
File1.txt
ABC
BDF
GHJ
base.csv(尝试用逗号分隔并制表符分隔)
line 1,,,,"hfhf,ferf,ju,ABC"
line 2 ,,,,,"ewy,trggt,gtg,ABC,RFR"
line 3 .."himk,n,hn.ujj., BDF"
等
建议的输出类似
ABC
line 1..
line 2..(whole lines)
BDF
line 3..
以此类推,针对文件1中的每个模式
我尝试的代码是:
#!/bin/bash
for i in *.txt -# cycle through all files containing pattern lists
do
for q in "$i"; # # cycle through list
do
echo $q >>output.${i};
grep -f "${q}" base.csv >>output.${i};
echo "\n";
done
done
但是输出仅是文件名,然后是一些没有模式名称的字符串列表,例如
File1.txt
line 1...
line 2...
line 3..
所以我不知道每个字符串属于什么模式,必须手动检查和分配。你能指出我的错误吗?谢谢!
答案 0 :(得分:1)
grep
可以一次处理多个文件,然后增加了吸引人的好处,那就是表明它找到了匹配的文件。
grep -f File1.txt base.csv >output.txt
不清楚您希望内部循环做什么;它只会一次循环一个令牌,因此根本不是一个循环。
如果您希望按模式将输出分组,那么这是一个for
循环,它一次查找一个模式:
while read -r pat; do
echo "$pat"
grep "$pat" *.txt
done <File1.txt >output.txt
但是解决此问题的最有效方法是编写一个简单的Awk脚本,该脚本可立即处理所有输入文件,并在打印匹配项之前对其进行分组。
另一个问题是锚点。 grep "ABC"
将在123DEABCXYZ
中找到一个匹配项;您要避免这种事情吗?您可以改进正则表达式,或者再次使用Awk,它使您可以更好地控制在结构化行中准确查找匹配项的位置。
awk '# Read patterns into memory
NR==FNR { a[++i] = $1; next }
# Loop across patterns
{ for(j=1; j<=i; ++j)
if($0 ~ a[j]) {
print FILENAME ":" FNR ":" $0 >>output.a[j]
next }
}' File1.txt base.csv
答案 1 :(得分:0)
您实际上并没有在读取文件,只是在处理文件名。试试这个:
#!/bin/bash
for i in *.txt # cycle through all files containing pattern lists
do
while read -r q # read file line by line
do
echo "$q" >>"output.${i}"
grep -f "${q}" base.csv >>"output.${i}"
echo "\n"
done < "${i}"
done
答案 2 :(得分:0)
这是一个将split
到数组(file2
)中的单词(用word[]
隔开,用引号和空格隔开的逗号分隔)并存储记录名称({ {1}}等),以逗号分隔:
line 1
输出:
awk '
NR==FNR {
n=split($0,tmp,/[" ]*(,|$)[" ]*/) # split words
for(i=2;i<=n;i++) # after first
if(tmp[i]!="") # non-empties
word[tmp[i]]=word[tmp[i]] (word[tmp[i]]==""?"":",") tmp[1] # hash rownames
record[tmp[1]]=$0 # store records
next
}
($1 in word) { # word found
n=split(word[$1],tmp,",") # get record names
print $1 ":" # output word
for(i=1;i<=n;i++) # and records
print record[tmp[i]]
}' file2 file1
答案 3 :(得分:0)
我的朋友,感谢您的帮助。 尝试了以上两种变体,但不断出现各种错误(预期为“执行”)或行为异常(获取模式块的名称,例如ABC,BDF,但没有行。 放弃了一段时间,然后最终尝试了另一种方法 虽然基本目标是循环浏览模式列表文件,但在巨大的文件中搜索模式,并从找到的行中写出特定的列-我只是写了
for *i in *txt # cycle throughfiles w/ patterns
do
grep -F -f "$i" bigfile.csv >> ${i}.out1 #greps all patterns from current file
cut -f 2,3,4,7 ${i}.out1>> ${i}.out2 # cuts columns of interest and writes them out to another file
done
我知道应该使用一些新颖的管道功能来改进此代码,但是它可以正常工作,希望能对类似情况的人有所帮助。您可以轻松添加一些回声以按照我最初的要求写出模式列表名称