Как перебрать строки в STDIN и запустить команду оболочки?

Похоже, вам не нравится подсказка, которая есть у обычного пользователя.

На этой странице описывается, как изменить подсказку.

Выполнение следующей команды изменит вашу подсказку:

PS1="[\\u@\\h:\\w] $"

приведет к [username@hostname:working-directory] $

Если вы хотите, чтобы ваше приглашение было только $, вы можете использовать следующую строку:

PS1="$ "

Добавление вышеуказанной строки в ваш ~/. bashrc установит подсказку для всего, что вы вошли в систему

PS1 — значение этого параметра расширено (см. PROMPTING ниже) и используется в качестве основной строки подсказки. Значение по умолчанию \s-\v\$ .

Bash позволяет настраивать эти строки подсказок, вставляя количество специальных символов с обратной косой чертой, которые декодируются как следующим образом:

\a : an ASCII bell character (07)
\d : the date in “Weekday Month Date” format (e.g., “Tue May 26”)
\D{format} : the format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation. The braces are required
\e : an ASCII escape character (033)
\h : the hostname up to the first ‘.’
\H : the hostname
\j : the number of jobs currently managed by the shell
\l : the basename of the shell’s terminal device name
\n : newline
\r : carriage return
\s : the name of the shell, the basename of $0 (the portion following the final slash)
\t : the current time in 24-hour HH:MM:SS format
\T : the current time in 12-hour HH:MM:SS format
\@ : the current time in 12-hour am/pm format
\A : the current time in 24-hour HH:MM format
\u : the username of the current user
\v : the version of bash (e.g., 2.00)
\V : the release of bash, version + patch level (e.g., 2.00.0)
\w : the current working directory, with $HOME abbreviated with a tilde
\W : the basename of the current working directory, with $HOME abbreviated with a tilde
\! : the history number of this command
\# : the command number of this command
\$ : if the effective UID is 0, a #, otherwise a $
\nnn : the character corresponding to the octal number nnn
\\ : a backslash
\[ : begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
\] : end a sequence of non-printing characters

0
10.04.2017, 01:01
4 ответа
echo "mbar bar\nmbaz baz" | xargs mv

В xargs вы должны использовать параметр -t , чтобы узнать, что происходит. Итак, в приведенном выше случае, если бы мы вызывали xargs с помощью -t , что мы видим:

mv mbar bar mbaz baz

Очевидно, это неверно. Случилось так, что xargs , как голодный крокодил, съел все аргументы, подаваемые ему через трубу echo . Итак, вам нужен способ ограничить передачу аргументов крокодилу. А так как вы запрашивали построчно, вам нужна опция -l или -L для POSIX.

echo "mbar bar\nmbaz baz" | xargs -l -t mv

POSIX-способ:

echo "mbar bar\nmbaz baz" | xargs -L 1 -t mv

mv mbar bar
mv mbaz baz

И это то, что вы хотели. HTH

3
28.01.2020, 02:16

xargs может вести себя не так, как вы ожидаете. См. Комментарий @ MichaelHomer к этому вопросу:

xargs mv mfoo foo будет ждать ввода и запускать mv mfoo foo $ x_1 $ x_2 $ x_3 ... для каждой строки $ x_n вводимых данных. @MichaelHomer

Это можно подтвердить, прочитав справочную страницу xargs :

ОПИСАНИЕ
Утилита xargs считывает пробел, табуляцию, новую строку и конец -файлы с разделителями строк из стандартного ввода и выполняет утилиту со строками в качестве аргументов.

На практике кажется, что xargs будет игнорировать символы новой строки при передаче аргументов в утилиту командной строки, указанную в качестве первого аргумента.Например, обратите внимание, что происходит с новой строкой:

$ echo "foo bar\ncat dog"
foo bar
cat dog
$ echo "foo bar\ncat dog" | xargs echo
foo bar cat dog

Этим поведением можно управлять с помощью флага -n :

-n число

Установить максимальное количество аргументов, взятых из стандартный ввод для
каждого вызова утилиты.

Возвращаясь к предыдущему примеру, если мы хотим, чтобы xargs принимал только 2 аргумента, а затем завершился, мы можем использовать подход @ ddnomad :

$ echo "foo bar\ncat dog" | xargs -n 2 echo
foo bar
cat dog

Также, как показано в комментариях в Ответ Ракеша Шармы: в BSD xargs вы можете указать количество строк для чтения с помощью флага -L . На странице руководства:

-L номер

Вызов утилиты для каждой прочитанной числовой строки. Если достигнут EOF и на
было прочитано меньше строк, чем число, то будет вызвана утилита с доступными строками.

Не менее полезен для тестирования переключатель -t :

Возвращаясь к нашему примеру, оба следующих примера будут работать; однако второй пример лучше, потому что это то, что предполагалось в данном случае:

$ echo "foo bar\ncat dog" | xargs -n 2 echo
foo bar
cat dog
$ echo "foo bar\ncat dog" | xargs -L 1 echo
foo bar
cat dog

Примечание из справочной страницы:

Параметры -L и -n взаимоисключающие; будет использован последний из указанных.

0
28.01.2020, 02:16

Вы можете пойти этим путем:

echo -e "foo bar\ndoo dar" | xargs -n 2 mv

Для чтения из файла:

cat lines.txt | xargs -n 2 mv

или

xargs -a lines.txt -n 2 mv
2
28.01.2020, 02:16

Существует очень простое решение, которое не использует xargs.
Определите эту функцию:

$ mv2() { while (($# >1 )); do echo mv "$1" "$2"; shift 2; done; }

Затем просто вызовите ее со списком необходимых имен файлов (новые строки не требуются):

$ mv2 mbar bar mbaz baz
mv mbar bar
mv mbaz baz

Удалите эхо, чтобы функция действительно работала.

0
28.01.2020, 02:16

Теги

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