Если вы измените уровень масштабирования и настроите на вид значка в определенной папке, он «запомнит» это до большого, но конечного количества папок.
Мое предложение:
IFS=; while read -r word; do printf "%s " $word; grep -o $word b | wc -l; done < a
, используя while, мы зацикливаемся на слова (файл a) printf "%s " $word: печатает имя слова, например: ABCD grep -o $word b | wc -l: подсчитывает и печатает номер вхождения Мое предложение:
IFS=; while read -r word; do printf "%s " $word; grep -o $word b | wc -l; done < a
, используя while, мы зацикливаемся на слова (файл a) printf "%s " $word: печатает имя слова, например: ABCD grep -o $word b | wc -l: подсчитывает и печатает номер вхождения Мое предложение:
IFS=; while read -r word; do printf "%s " $word; grep -o $word b | wc -l; done < a
, используя while, мы зацикливаемся на слова (файл a) printf "%s " $word: печатает имя слова, например: ABCD grep -o $word b | wc -l: подсчитывает и печатает номер вхождения count_patterns.py. Должно быть достаточно хорошо для больших файлов. Использует OrderedDict для записи всех паттернов из файла A, предоставленных в командной строке, и ищет их в файле B.
#!/usr/bin/env python3
import sys
from collections import OrderedDict as od
pattern=od()
with open(sys.argv[1]) as pattern_file, open(sys.argv[2]) as data_file:
for line in pattern_file:
pattern[line.strip()]=0
for line in data_file:
for p in pattern.keys():
pattern[p]+=line.strip().count(p)
for key,val in pattern.items():
print(key,val)
Использование:
$ ./count_patterns.py file_A.txt file_B.txt
ABCD 4
EFG 3
HIJKL 0
MNO 1
PQRSTU 0
Здесь используется подстановка процесса из sed, которая позволяет разделить файл A на строки новой строки в ** и использовать grep -c для подсчета числа совпадающих строк.
[ f3]Не лучший способ сделать это, возможно, не подходит для больших файлов, но работает. Не рекомендуется использовать метод bash, но если набор данных невелик, он будет работать.
Использование ассоциативных массивов Bash:
#!/bin/bash
set -eu
declare -A patterns
while IFS= read -r p; do
patterns["$p"]=0
done < "$1"
while IFS='*' read -ra l; do
for r in "${l[@]}"; do
if [ -n "$r" ] && [ -v patterns["$r"] ]; then
patterns[$r]=$((${patterns["$r"]} + 1))
fi
done
done < "$2"
for p in "${!patterns[@]}"; do
printf '%s\t%u\n' "$p" "${patterns["$p"]}"
done
Использование:
bash count-patterns.sh pattern-list.txt word-list.txt
Использование пользовательского словарный класс и обработка функциональных стилей:
#!/usr/bin/env python3
import sys, itertools, collections
class MyCounter(collections.UserDict):
def __init__(self, _dict):
self.data = _dict
def update(self, iterable):
for key in iterable:
self.data[key] += 1
with open(sys.argv[1]) as pattern_file:
patterns = MyCounter({ s.rstrip('\n'): 0 for s in pattern_file })
with open(sys.argv[2]) as wordlist_file:
patterns.update(filter(patterns.__contains__,
itertools.chain.from_iterable(map(
lambda s: s.rstrip('\n').split('**'), wordlist_file))))
for p in patterns.items():
print(*p, sep='\t')
Использование:
python3 count-patterns.py pattern-list.txt word-list.txt
#include <cstddef>
#include <utility>
#include <unordered_map>
#include <iostream>
#include <fstream>
namespace std
{
template <class Ch, class Tr, class K, class V, class H, class Eq>
basic_ostream<Ch,Tr> &operator<<( basic_ostream<Ch,Tr> &os,
const std::unordered_map<K,V,H,Eq> &m )
{
for (const typename std::unordered_map<K,V,H,Eq>::value_type &i: m)
os << i.first << '\t' << i.second << '\n';
return os.flush();
}
}
template <class Key, class Hash = std::hash<Key>, class Equal = std::equal_to<Key>>
class counter :
public std::unordered_map<Key, std::size_t, Hash, Equal>
{
private:
typedef std::unordered_map<Key, std::size_t, Hash, Equal> _base;
public:
void update_existing( const Key &k, std::size_t count = 1 )
{
const typename _base::iterator match = this->find(k);
if (match != this->end())
match->second += count;
}
};
int main( int argc, char *argv[] )
{
if (argc != 3)
{
std::cerr << "Usage: " << argv[0] << " <PATTERN-FILE> <WORDLIST-FILE>" << std::endl;
return 2;
}
counter<std::string> patterns;
std::string buf;
{
std::ifstream pattern_file(argv[1]);
while (pattern_file.good() && !std::getline(pattern_file, buf).fail())
patterns.emplace(std::move(buf), 0);
}
if (!patterns.empty())
{
std::ifstream wordlist_file(argv[2]);
while (wordlist_file.good() && !std::getline(wordlist_file, buf).fail())
{
static const char delim[] = {'*', '*'};
std::size_t offset = 0, p = 0;
while ((p = buf.find(delim, offset, sizeof(delim))) != std::string::npos)
{
patterns.update_existing(buf.substr(offset, p - offset));
offset = p + sizeof(delim);
}
patterns.update_existing(buf.erase(0, offset));
}
}
std::cout << patterns;
}
Скомпилировать с:
c++ -std=c++11 -o count-patterns count-patterns.cpp
Использование:
./count-patterns pattern-list.txt word-list.txt
Вот программа awk, которая должна делать то, что вам нужно:
BEGIN {FS="*"}
FNR==NR {a[$0]=0; next}
{for (i=1; i<=NF; i++) if ($i in a) a[$i]++}
END {
for (i in a) {
print i, a[i]
}
}
awk -f test.awk fileA DB
ABCD 2
HIJKL 0
EFG 3
MNO 0
PQRSTU 0
Использование ассоциативных массивов Bash:
#!/bin/bash
set -eu
declare -A patterns
while IFS= read -r p; do
patterns["$p"]=0
done < "$1"
while IFS='*' read -ra l; do
for r in "${l[@]}"; do
if [ -n "$r" ] && [ -v patterns["$r"] ]; then
patterns[$r]=$((${patterns["$r"]} + 1))
fi
done
done < "$2"
for p in "${!patterns[@]}"; do
printf '%s\t%u\n' "$p" "${patterns["$p"]}"
done
Использование:
bash count-patterns.sh pattern-list.txt word-list.txt
Использование пользовательского словарный класс и обработка функциональных стилей:
#!/usr/bin/env python3
import sys, itertools, collections
class MyCounter(collections.UserDict):
def __init__(self, _dict):
self.data = _dict
def update(self, iterable):
for key in iterable:
self.data[key] += 1
with open(sys.argv[1]) as pattern_file:
patterns = MyCounter({ s.rstrip('\n'): 0 for s in pattern_file })
with open(sys.argv[2]) as wordlist_file:
patterns.update(filter(patterns.__contains__,
itertools.chain.from_iterable(map(
lambda s: s.rstrip('\n').split('**'), wordlist_file))))
for p in patterns.items():
print(*p, sep='\t')
Использование:
python3 count-patterns.py pattern-list.txt word-list.txt
#include <cstddef>
#include <utility>
#include <unordered_map>
#include <iostream>
#include <fstream>
namespace std
{
template <class Ch, class Tr, class K, class V, class H, class Eq>
basic_ostream<Ch,Tr> &operator<<( basic_ostream<Ch,Tr> &os,
const std::unordered_map<K,V,H,Eq> &m )
{
for (const typename std::unordered_map<K,V,H,Eq>::value_type &i: m)
os << i.first << '\t' << i.second << '\n';
return os.flush();
}
}
template <class Key, class Hash = std::hash<Key>, class Equal = std::equal_to<Key>>
class counter :
public std::unordered_map<Key, std::size_t, Hash, Equal>
{
private:
typedef std::unordered_map<Key, std::size_t, Hash, Equal> _base;
public:
void update_existing( const Key &k, std::size_t count = 1 )
{
const typename _base::iterator match = this->find(k);
if (match != this->end())
match->second += count;
}
};
int main( int argc, char *argv[] )
{
if (argc != 3)
{
std::cerr << "Usage: " << argv[0] << " <PATTERN-FILE> <WORDLIST-FILE>" << std::endl;
return 2;
}
counter<std::string> patterns;
std::string buf;
{
std::ifstream pattern_file(argv[1]);
while (pattern_file.good() && !std::getline(pattern_file, buf).fail())
patterns.emplace(std::move(buf), 0);
}
if (!patterns.empty())
{
std::ifstream wordlist_file(argv[2]);
while (wordlist_file.good() && !std::getline(wordlist_file, buf).fail())
{
static const char delim[] = {'*', '*'};
std::size_t offset = 0, p = 0;
while ((p = buf.find(delim, offset, sizeof(delim))) != std::string::npos)
{
patterns.update_existing(buf.substr(offset, p - offset));
offset = p + sizeof(delim);
}
patterns.update_existing(buf.erase(0, offset));
}
}
std::cout << patterns;
}
Скомпилировать с:
c++ -std=c++11 -o count-patterns count-patterns.cpp
Использование:
./count-patterns pattern-list.txt word-list.txt
count_patterns.py. Должно быть достаточно хорошо для больших файлов. Использует OrderedDict для записи всех паттернов из файла A, предоставленных в командной строке, и ищет их в файле B.
#!/usr/bin/env python3
import sys
from collections import OrderedDict as od
pattern=od()
with open(sys.argv[1]) as pattern_file, open(sys.argv[2]) as data_file:
for line in pattern_file:
pattern[line.strip()]=0
for line in data_file:
for p in pattern.keys():
pattern[p]+=line.strip().count(p)
for key,val in pattern.items():
print(key,val)
Использование:
$ ./count_patterns.py file_A.txt file_B.txt
ABCD 4
EFG 3
HIJKL 0
MNO 1
PQRSTU 0
Здесь используется подстановка процесса из sed, которая позволяет разделить файл A на строки новой строки в ** и использовать grep -c для подсчета числа совпадающих строк.
$ cat file_B.txt
ABCD**FORNTUFPSRWSABCFYWSZCFTHBFORTYBJNF**ABCD**D**EFG**ACVRT**EFG**PQRMNOOPQ**EFG**ZXXXYY
ABCD**FORNTUFPSRWSABCFYWSZCFTHBFORTYBJNF**ABCD
$ cat file_A.txt
ABCD
EFG
HIJKL
MNO
PQRSTU
$ while IFS= read -r pattern; do printf "%s\t" "$pattern"; grep -c "$pattern" < <( sed 's/\*\*/\n/g' file_B.txt ); done < file_A.txt
ABCD 4
EFG 3
HIJKL 0
MNO 1
PQRSTU 0
Не лучший способ сделать это, возможно, не подходит для больших файлов, но работает. Не рекомендуется использовать метод bash, но если набор данных невелик, он будет работать.
Вот программа awk, которая должна делать то, что вам нужно:
BEGIN {FS="*"}
FNR==NR {a[$0]=0; next}
{for (i=1; i<=NF; i++) if ($i in a) a[$i]++}
END {
for (i in a) {
print i, a[i]
}
}
awk -f test.awk fileA DB
ABCD 2
HIJKL 0
EFG 3
MNO 0
PQRSTU 0
Использование ассоциативных массивов Bash:
#!/bin/bash
set -eu
declare -A patterns
while IFS= read -r p; do
patterns["$p"]=0
done < "$1"
while IFS='*' read -ra l; do
for r in "${l[@]}"; do
if [ -n "$r" ] && [ -v patterns["$r"] ]; then
patterns[$r]=$((${patterns["$r"]} + 1))
fi
done
done < "$2"
for p in "${!patterns[@]}"; do
printf '%s\t%u\n' "$p" "${patterns["$p"]}"
done
Использование:
bash count-patterns.sh pattern-list.txt word-list.txt
Использование пользовательского словарный класс и обработка функциональных стилей:
#!/usr/bin/env python3
import sys, itertools, collections
class MyCounter(collections.UserDict):
def __init__(self, _dict):
self.data = _dict
def update(self, iterable):
for key in iterable:
self.data[key] += 1
with open(sys.argv[1]) as pattern_file:
patterns = MyCounter({ s.rstrip('\n'): 0 for s in pattern_file })
with open(sys.argv[2]) as wordlist_file:
patterns.update(filter(patterns.__contains__,
itertools.chain.from_iterable(map(
lambda s: s.rstrip('\n').split('**'), wordlist_file))))
for p in patterns.items():
print(*p, sep='\t')
Использование:
python3 count-patterns.py pattern-list.txt word-list.txt
#include <cstddef>
#include <utility>
#include <unordered_map>
#include <iostream>
#include <fstream>
namespace std
{
template <class Ch, class Tr, class K, class V, class H, class Eq>
basic_ostream<Ch,Tr> &operator<<( basic_ostream<Ch,Tr> &os,
const std::unordered_map<K,V,H,Eq> &m )
{
for (const typename std::unordered_map<K,V,H,Eq>::value_type &i: m)
os << i.first << '\t' << i.second << '\n';
return os.flush();
}
}
template <class Key, class Hash = std::hash<Key>, class Equal = std::equal_to<Key>>
class counter :
public std::unordered_map<Key, std::size_t, Hash, Equal>
{
private:
typedef std::unordered_map<Key, std::size_t, Hash, Equal> _base;
public:
void update_existing( const Key &k, std::size_t count = 1 )
{
const typename _base::iterator match = this->find(k);
if (match != this->end())
match->second += count;
}
};
int main( int argc, char *argv[] )
{
if (argc != 3)
{
std::cerr << "Usage: " << argv[0] << " <PATTERN-FILE> <WORDLIST-FILE>" << std::endl;
return 2;
}
counter<std::string> patterns;
std::string buf;
{
std::ifstream pattern_file(argv[1]);
while (pattern_file.good() && !std::getline(pattern_file, buf).fail())
patterns.emplace(std::move(buf), 0);
}
if (!patterns.empty())
{
std::ifstream wordlist_file(argv[2]);
while (wordlist_file.good() && !std::getline(wordlist_file, buf).fail())
{
static const char delim[] = {'*', '*'};
std::size_t offset = 0, p = 0;
while ((p = buf.find(delim, offset, sizeof(delim))) != std::string::npos)
{
patterns.update_existing(buf.substr(offset, p - offset));
offset = p + sizeof(delim);
}
patterns.update_existing(buf.erase(0, offset));
}
}
std::cout << patterns;
}
Скомпилировать с:
c++ -std=c++11 -o count-patterns count-patterns.cpp
Использование:
./count-patterns pattern-list.txt word-list.txt
Вот программа awk, которая должна делать то, что вам нужно:
BEGIN {FS="*"}
FNR==NR {a[$0]=0; next}
{for (i=1; i<=NF; i++) if ($i in a) a[$i]++}
END {
for (i in a) {
print i, a[i]
}
}
awk -f test.awk fileA DB
ABCD 2
HIJKL 0
EFG 3
MNO 0
PQRSTU 0