Подсчет количества вхождений символов в строке
У меня есть файл, который выглядит следующим образом: (Примечание: A*, B*, C* являются заполнителями). Файл ограничен ;
AAAA;BBBB;CCCCCCCC;DD;EEEEEEEE;FF;
AAA1;BBBBB;CCCC;DD;EEEEEEEE;FFFFF;
AAA3;BB;CCCC;DDDDDDDDD;EEEEEEE;FF;
Я пытаюсь написать небольшой скрипт, который подсчитывает количество вхождений разделителя ;
и если оно меньше или больше 5, выведите указанную строку в текстовый файл.
delim=";"
while read line
do
n_of_occ=$(grep -o "$delim" <<< "$line" | wc -l)
if [[ $n_of_occ < 5 ]] || [[ $n_of_occ > 5 ]]
then
echo $line >> outfile
fi
done
По некоторым причинам, это не работает, и мой вывод искажен. Может ли кто-нибудь помочь или предложить другой способ решения этой проблемы? Возможно с Perl вместо bash?
5 ответов
К сожалению, каждая строка в ваших данных образца имеет шесть точек с запятой, что означает, что все они должны быть напечатаны. Тем не менее, вот решение Perl, состоящее из одной строки
$ perl -ne'print if tr/;// != 5' aaa.csv
AAAA;BBBB;CCCCCCCC;DD;EEEEEEEE;FF;
AAA1;BBBBB;CCCC;DD;EEEEEEEE;FFFFF;
AAA3;BB;CCCC;DDDDDDDDD;EEEEEEE;FF;
Легко в Perl:
perl -ne 'print if tr/;// != 5' input_file > output_file
-n
читает входные данные построчноtr
оператор возвращает количество совпадений
Я бы взял эту однострочную:
awk '{x=$0}gsub(";","",x)!=5' file
С помощью sed вы можете сделать это:
sed '/^\([^;]*;\)\{5\}$/d' file > outfile
Удаляет строки ровно с 5 запятыми (;
) и отправляет вывод в outfile.
Или, если вы хотите, чтобы ваш собственный код работал, внесите следующие изменения:
- замещать
done
сdone <file
- замещать
[[
с((
а также]]
с))
т.е. использовать((...))
вместо[[...]]