У меня есть предложение вроде
Это, например,
Я хочу записать это в файл, чтобы каждое слово в этом предложении записывалось в отдельную строку.
Как это сделать в сценариях оболочки?
У меня есть предложение вроде
Это, например,
Я хочу записать это в файл, чтобы каждое слово в этом предложении записывалось в отдельную строку.
Как это сделать в сценариях оболочки?
Несколько способов сделать это, выбрать свой любимый!
echo "This is for example" | tr ' ' '\n' > example.txt
или просто сделайте это, чтобы избежать ненужного использования echo
:
tr ' ' '\n' <<< "This is for example" > example.txt
Обозначение <<<
используется с herestring
Или используйте sed
вместо tr
:
sed "s/ /\n/g" <<< "This is for example" > example.txt
Для еще большего количества альтернатив, проверьте ответы других пользователей =)
$ echo "This is for example" | xargs -n1
This
is
for
example
Попробуйте использовать:
string="This is for example"
printf '%s\n' $string > filename.txt
или воспользовавшись bash word -расщепление
string="This is for example"
for word in $string; do
echo "$word"
done > filename.txt
example="This is for example"
printf "%s\n" $example
Попробуйте использовать:
str="This is for example"
echo -e ${str// /\\n} > file.out
Выход
> cat file.out
This
is
for
example
Вы заботитесь о знаках препинания? Например, в некоторых вызовах вы можете увидеть, например, "слово", подобное (и т.д.), Точно в скобках. Или слово будет "круглые скобки". а не "круглые скобки". Если вы анализируете файл с правильными предложениями, это может быть проблемой, особенно если вы хотите отсортировать по слову или даже получить количество слов для каждого слова.
Есть способы справиться с этим, но есть некоторые предостережения и, безусловно, есть место для улучшения. Это происходит с числами, тире (в числах) и десятичных точках/точках (в числах). Возможно, наличие точного набора правил поможет решить эту проблему, но приведенные ниже примеры могут дать вам некоторые вещи для работы. Я сделал несколько надуманных входных примеров, чтобы продемонстрировать эти недостатки (или как вы хотите их назвать).
$ echo "This is an example sentence with punctuation marks and digits i.e. , . ; \! 7 8 9" | grep -o -E '\<[A-Za-z0-9.]*\>'
This
is
an
example
sentence
with
punctuation
marks
and
digits
i.e
7
8
9
Как вы можете видеть, то есть "ie" оказывается просто ie, а знаки препинания в противном случае не отображаются. Хорошо, но это оставляет такие вещи, как номера версий в виде major.minor.revision-release, например, 0.0.1-1; это тоже можно показать? Да:
$ echo "The current version is 0.0.1-1. The previous version was current from 2017-2018."|grep -o -E '\<[-A-Za-z0-9.]*\>'
The
current
version
is
0.0.1-1
The
previous
version
was
current
from
2017-2018
Обратите внимание, что предложения не заканчиваются с полной остановкой. Что произойдет, если вы добавите пробел между годами и тире? Вы не будете иметь черту, но каждый год будет на своей линии:
$ echo "2017 - 2018" | grep -o -E '\<[-A-Za-z0-9.]*\>'
2017
2018
Тогда возникает вопрос, если хотите -
сами по себе быть посчитанными; по самой природе разделения слов у вас не будет лет в виде одной строки, если есть пробелы. Потому что это не слово само по себе, я бы подумал, что нет.
Я уверен, что это может быть упрощено в дальнейшем. Кроме того, если вам вообще не нужны знаки препинания или цифры, вы можете изменить их на:
$ echo "The current version is 0.0.1-1. The previous version was current from 2017-2018."|grep -o -E '\<[A-Za-z]*\>'
The
current
version
is
The
previous
version
was
current
from
Если вы хотите иметь номера:
$ echo "The current version is 0.0.1-1. The previous version was current from 2017-2018."|grep -o -E '\<[A-Za-z0-9]*\>'
The
current
version
is
0
0
1
1
The
previous
version
was
current
from
2017
2018
Что касается "слов" с буквами и цифрами, то это еще одна вещь, которая может или не может быть рассмотрена, но демонстрирует вышесказанное:
$ echo "The current version is 0.0.1-1. test1."|grep -o -E '\<[A-Za-z0-9]*\>'
The
current
version
is
0
0
1
1
test1
Выводит их. Но следующее не (потому что это вообще не учитывает числа):
$ echo "The current version is 0.0.1-1. test1."|grep -o -E '\<[A-Za-z]*\>'
The
current
version
is
Знаки препинания довольно легко игнорировать, но в некоторых случаях может возникнуть необходимость или желание в них. В случае, например, я полагаю, вы могли бы использовать say для изменения строк, например, например, но это было бы личное предпочтение, я думаю.
Я могу суммировать, как это работает, но только справедливо; Я слишком устал, чтобы даже думать о многом:
Я объясню только вызов grep -o -E '\<[-A-Za-z0-9.]*\>'
Но во многом он такой же в других (символ вертикальной черты/трубы в расширенном grep допускает более одного шаблона):
Опция -o
предназначена только для печати совпадений, а не всей строки. -E
предназначен для расширенного grep (с таким же успехом можно использовать egrep). Что касается самого регулярного выражения:
<\
И \>
- границы слов (начинающиеся и заканчивающиеся соответственно - вы можете указать только одну, если хотите); Я считаю, что опция -w
- это то же самое, что и указание обоих, но, возможно, вызов немного отличается (на самом деле я не знаю).
'\<[-A-Za-z0-9.]*\>'
Говорит тире, заглавные и строчные буквы и точку ноль или более раз. Что касается того, почему тогда это превращается, например, в .eg, я в это время могу только сказать, что это - образец, но у меня нет способностей, чтобы рассмотреть это больше.
#!/bin/bash
if [ $# -eq 0 ]; then
echo "Usage: $(basename ${0}) <FILE> [FILE...]"
exit 1
fi
for file do
if [ -e "${file}" ]
then
echo "** ${file}: "
grep -o -E '\<[-A-Za-z0-9.]*\>' "${file}"|sort | uniq -c | sort -rn
else
echo >&2 "${1}: file not found"
continue
fi
done
Пример:
$ cat example
The current version is 0.0.1-1 but the previous version was non-existent.
This sentence contains an abbreviation i.e. e.g. (so actually two abbreviations).
This sentence has no numbers and no punctuation
$ ./wordfreq example
** example:
2 version
2 sentence
2 no
2 This
1 was
1 two
1 the
1 so
1 punctuation
1 previous
1 numbers
1 non-existent
1 is
1 i.e
1 has
1 e.g
1 current
1 contains
1 but
1 and
1 an
1 actually
1 abbreviations
1 abbreviation
1 The
1 0.0.1-1
NB. Я не транслитерировал прописные буквы в строчные, поэтому слова "и" отображаются как разные слова. Если вы хотите, чтобы все они были в нижнем регистре, вы можете изменить вызов grep в сценарии, чтобы он передавался в tr перед сортировкой:
grep -o -E '\<[-A-Za-z0-9.]*\>' "${file}"|tr '[A-Z]' '[a-z]'|sort | uniq -c | sort -rn
Да, и так как вы спросили, хотите ли вы записать его в файл, вы можете просто добавить его в командную строку (это для необработанного вызова):
> output_file
Для сценария вы бы использовали его так:
$ ./wordfreq file1 file2 file3 > output_file