Мне бы хотелось извлечь символы между первым и вторым подчеркиванием имен файлов в папке и подсчитать количество файлов такого типа, присутствующих в ней.
Папка содержит файлы в определенном формате, например:
2305195303310_ABC_A08_1378408840043.hl7
2305195303310_ABC_A08_1378408840043.hl7
Q37984932T467566261_DEF_R03_1378825633215.hl7
37982442T467537201_DEF_R03_1378823455384.hl7
37982442T467537201_MNO_R03_1378823455384.hl7
2305195303310_ABC_A08_1378408840053.hl7
Q37984932T467566261_DEF_R03_1378825633215.hl7
37982442T467537201_MNO_R03_1378823455384.hl7
И так далее…
Вывод скрипта должен дать мне следующий результат:
ABC 3
DEF 3
MNO 2
решение1
ls | cut -d_ -f2 | sort | uniq -c
решение2
Вы можете сделать это классическим способом *nix, объединяя небольшие команды вместе. Сначала найдите интересующие вас файлы, для этого вы можете использовать shellподстановка:
for i in *_*_*; do echo "$i"; done
Эта команда выведет все файлы в текущем каталоге, имя которых содержит два подчеркивания. Чтобы извлечь строку между этими подчеркиваниями, вы можете использоватьcut
, сообщая ему, что нужно использовать его _
в качестве разделителя полей и вывести второе поле:
cut -d '_' -f 2
Прохождение первой команды через вторую выведет интересующие вас строки, но также выведет пустую строку в тех случаях, когда между подчеркиваниями нет символа ( foo__bar
например). Вы можете отфильтровать их, используя , grep .
который выведет только строки, содержащие хотя бы один символ (включая пробел). Наконец, вы можете подсчитать, пропустив вывод черезsort
иuniq -c
.
Собрав все это вместе, вы получите:
$ for i in *_*_*; do echo "$i" | cut -d '_' -f 2 ; done |
grep . | sort | uniq -c
3 ABC
2 DEF
1 MNO
Если вы действительно хотите, чтобы число было на другой стороне, вы можете использовать awk
:
$ for i in *_*_*; do echo "$i" | cut -d '_' -f 2 ; done |
grep . | sort | uniq -c | awk '{print $2,$1}'
ABC 3
DEF 2
MNO 1
решение3
Вот как можно выполнить эту работу с помощью Perl.
perl -aE '/^[^_]+_\K[^_]+/ && $h{$&}++}{say$_," ",$h{$_} for sort keys %h' file
ABC 3
DEF 3
MNO 2
Объяснение:
perl -aE # invoque Perl compiler with autosplit lines
/^[^_]+_\K[^_]+/ # match non _ characters after the first _
&& # execute the next command if a match is found
$h{$&}++} # increment a counter for each match founded
{say$_," ",$h{$_} # finally print each match and the counter associated
for sort keys %h # for each sorted matches