Если вам нужен первый K
, просто избавьтесь от флага g
:
sed -i '4s/K/exc/' <newfile>
Если вы хотите заменить 2-ю, 3-ю и т. д. K
, используйте 2
, 3
, 4
вместоg
sed -i '4s/K/exc/2' <newfile>
sed -i '4s/K/exc/3' <newfile>
Если вы хотите заменить все K
с 3-го до конца (поддерживается только GNU sed):
echo 'KKKKKK' | sed s/K/E/3g
KKEEEE
Кстати, не используйте двойные кавычки ("
), если вы действительно не хотите вставлять переменные оболочки, расширения команд и т. д. в строку, переданную в sed
.
Я бы сделал:
something_with() {
printf 'Processing "%s"\n' "$1"
}
ret=0
if [ "$#" -gt 0 ]; then
# process args on command line
for arg do
something_with "$arg" || ret=$?
done
else
# no arg, processing lines of stdin instead:
while IFS= read -r "$arg" || [ -n "$arg" ]; do
# redirect something_with's stdin to /dev/null to make sure
# it doesn't interfere with the list of args.
</dev/null something_with "$arg" || ret=$?
done
fi
exit "$ret"
(обратите внимание, что это означает, что аргументы, отправляемые через стандартный ввод, не могут содержать символы новой строки ).
Хотя вы также можете принимать входные данные только в качестве аргументов, вызовите скрипт как:
xargs -rd '\n' -a input_file your-script
(здесь предполагается, что GNUxargs
)для xargs
передает содержимое строк в input_file
в качестве аргументов your-script
(, в этом случае your-script
может вызываться несколько раз xargs
для обхода ограничение на максимальное количество аргументов команды ).
В любом случае, я бы сказал, что вы не хотите проверять, является ли stdin каналом или нет.
Во-первых, что cat input_file | your-script
является Бесполезным Использованием Кошки(печально известным UUoC ). Как правило, если вы хотите передать содержимое файла в качестве входных данных для команды, вы используете < input_file your-scrip
или your-script < input_file
, и в этом случае стандартный ввод вашего скрипта не будет каналом (, если только input_file
сам по себе не является именованным каналом. ).
Ваш сценарий может быть вызван с помощью стандартного ввода, связанного с каналом, даже если вы не хотите, чтобы он читал его, как, например, в ssh host your-script arg1 arg2
(, где стандартный ввод является каналом для sshd
), ... | while IFS= read -r foo; do your-script "x$foo"; done
илиcmd | xargs your-script
(с некоторая xargs
реализация; вместо этого некоторые перенаправляют стандартный ввод на /dev/null ).
Но если вы действительно хотите, это уже рассмотрено в отдельном вопросе на этом сайте.:Как программа узнает, подключен ли стандартный вывод к терминалу или каналу? с той разницей, что здесь стандартный ввод вместо стандартного вывода, поэтому файловый дескриптор 0 вместо 1.
Вы можете проверить, является ли ваша оболочка интерактивной, через переменную $-
или через переменную $PS1
:
case "$-" in
*i*) echo This shell is interactive ;;
*) echo This shell is not interactive ;;
esac
или
if [ -z "$PS1" ]; then
echo This shell is not interactive
else
echo This shell is interactive
fi
Приведенные выше примеры скопированы из здесь .
Спасибо @Kusalananda :еще одна возможность проверить, переданы ли параметры в скрипт:
if [ -t 0 ]; then
echo "This shell is interactive"
fi