Это, вероятно, окончание строк в стиле Windows -, которое нарушает его. Вот как выглядит файл, сохраненный с окончаниями строк Windows, но прочитанный в стиле Unix:
#!/bin/sh^M
^M
echo "hello world"^M
При толковании шебанга (#! ), exec
увидит дополнительный возврат каретки (, обозначенный как CR
, \r
, ^M
), и не найдет/bin/sh^M
:
$ exec./setup.sh
bash: setup.sh: /bin/sh^M: bad interpreter: No such file or directory
Сохраните файл с окончаниями строк в стиле Unix -. В Windows достойные текстовые редакторы (Sublime Text, Notepad++, любая IDE и т. д. )должны уметь это делать. Существует также простой инструмент командной строки -под названием dos2unix, который делает именно то, что вы от него ожидаете.
Так и должно быть:
sed ':1;/-$/{N;b1};s/-\n//g;y/ /\n/' file | sort | uniq -c
С tr
+ sed
+ datamash
трубопроводом:
$ tr ' ' '\n' <file | sed '/-/N;s/-\n//' | datamash -s -g1 --output-delimiter=':' count 1
hello:2
helo:1
test:2
words:2
world:2
Для этого удобен Perl. :Переключатель -0777 будет поглощать весь файл в одну строку
perl -0777 -ne '
s/-\n//g; # join the hyphenated words
$count{$_}++ for split; # count all the words
while (($k,$v) = each %count) {print "$k:$v\n"}
' file
world:2
helo:1
hello:2
words:2
test:2
Вывод будет произвольным.
А вот еще более непонятный:tcl . В tclsh нет хорошей опции -e
, как в других языках, так что один лайнер -требует больше работы. Преимущество этого в том, что порядок слов в файле сохраняется.
echo '
set fh [open [lindex $argv 1] r]
set data [read -nonewline $fh]
close $fh
foreach word [split [string map {"-\n" ""} $data]] {
dict incr count $word
}
dict for {k v} $count {puts "$k:$v"}
' | tclsh -- file
hello:2
world:2
test:2
helo:1
words:2