Как я могу определить, что пользовательский ввод поступает из конвейера или с параметрами? (как с использованием «если еще»)

Если вам нужен первый 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.

0
11.05.2020, 13:50
2 ответа

Я бы сделал:

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 каналом или нет.

  1. Во-первых, что cat input_file | your-scriptявляется Бесполезным Использованием Кошки(печально известным UUoC ). Как правило, если вы хотите передать содержимое файла в качестве входных данных для команды, вы используете < input_file your-scripили your-script < input_file, и в этом случае стандартный ввод вашего скрипта не будет каналом (, если только input_fileсам по себе не является именованным каналом. ).

  2. Ваш сценарий может быть вызван с помощью стандартного ввода, связанного с каналом, даже если вы не хотите, чтобы он читал его, как, например, в 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.

1
28.04.2021, 23:15

Вы можете проверить, является ли ваша оболочка интерактивной, через переменную $-или через переменную $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
-2
28.04.2021, 23:15

Теги

Похожие вопросы