И в ksh, и в bash команда set -f
отключает создание имени файла («расширение имени пути»). Это эквивалентно установке параметра оболочки noglob
(в обеих оболочках).
Он не позволяет оболочке расширять шаблоны подстановки файлов:
$ ls -l
total 0
-rw-r--r-- 1 kk kk 0 Dec 30 21:39 hello
-rw-r--r-- 1 kk kk 0 Dec 30 21:39 world
$ echo *l[a-k]
world
$ echo *
hello world
$ set -o noglob
$ echo *
*
$ echo *l[a-k]
*l[a-k]
Чтобы отменить (очистить) настройку, используйте либо set + f
, либо set + o noglob
.
Есть пара проблем с вашим скриптом:
sed
после второй трубы ( |
). sed -i
сообщает sed
редактировать файлы «на месте», но файл не указан - sed
использует stdin
, исходящий от cat
. Вы можете безопасно удалить -i
, и теперь ваш сценарий должен работать. Фиксированный сценарий должен быть:
cat italian.txt | sed 's/sole/sun/g' | sed 's/penna/pen/g' > english.txt
Нет необходимости и излишне перезаписывать содержимое italian.txt, поскольку вывод sed
перенаправляется в другой файл с именем english.txt и все равно сохраняется. Также можно исключить бесполезное использование cat
sed -e 's/sole/sun/g' -e 's/penna/pen/g' italian.txt | tee english.txt
sed
позволяет использовать несколько переключателей -e
, что позволяет заменять более одного элемента за раз. tee
может использоваться для перенаправления данных (например, в другой файл с именем english.txt). Вы неправильно его используете.
Во-первых, вам не нужна кошка. sed
может принимать имя файла для чтения. Примерно так:
sed 's/sole/sun/g' italian.txt
Во-вторых, вам не нужно перенаправление конвейера для следующего sed
-выражения. Если вам это нужно, это должно выглядеть так:
sed 's/sole/sun/g' italian.txt | sed 's/penna/pen/g' > english.txt
, но это дополнительная работа. sed
может обрабатывать более одного выражения. Вы можете разделить их на «;» или передайте их sed
в качестве аргументов командной строки с -e
перед каждым из них.
В итоге команда выглядит так:
sed 's/sole/sun/g; s/penna/pen/g' italian.txt > english.txt
Вариант идеи @Kusalanananda :
$ cat dict
sole:sun
penna:pen
$ sed -f <(sed -r 's!(.+):(.+)!s/\\<\1\\>/\2/g!' dict) it.txt >en.txt
Если бы у вас был файл с парами слов, например
sole sun
penna pen
... и так далее для многих слов на итальянском и английском языках (нет практического ограничения, кроме памяти), то вы могли бы создать sed
скрипт
s/\<sole\>/sun/g
s/\<penna\>/pen/g
... (где \<слово\>
будет соответствовать только слову word
, а не e. word
или reword
) вот так:
$ awk '{ printf("s/\\<%s\\>/%s/g\n", $1, $2) }' pairs.txt >translate.sed
Затем вы можете применить этот сценарий sed
к текстовому файлу:
$ sed -f translate.sed italian.txt >english.txt