Если команда bash принимает имя файла в качестве последнего аргумента, можно ли использовать трубопровод для предоставления содержимого файла? - PullRequest
0 голосов
/ 29 мая 2019

Скажем, команда принимает имя файла в качестве последнего аргумента:

count-words "$word" file.txt

Есть ли способ использовать канал для предоставления содержимого файла вместо записи во временный файл?

Ответы [ 4 ]

2 голосов
/ 29 мая 2019

Я не уверен, правильно ли я понимаю ваше требование, но вы можете быть в ситуации, когда:

  • У вас есть программа (скажем, «generate-words»), которая печатает текст до stdout.
  • У вас также есть программа "count-words", которая считает данное слово в указанном текстовом файле.
  • Вы можете объединить две программы, написав вывод «generate-words» во временный файл file.txt.
  • Но вы хотите найти решение без записи во временный файл.

Если приведенные выше предположения верны, попробуйте:

count-words "$word" <(generate-words)

, где <(command) называется process substitution, и вы можете подключить вывод (stdout) command в другую программу, для которой требуется имя файла в качестве входа.

2 голосов
/ 29 мая 2019

Каждый аргумент, независимо от позиции, является символьной строкой, которую программа обрабатывает сама после того, как bash выполнит ее. bash не может вмешиваться в это.

Отдельные программы могут предоставлять возможность чтения из стандартного ввода или делать это по умолчанию, но если программа этого не делает, вам нужно указать его на файл в файловой системе.

1 голос
/ 29 мая 2019

Многие программы принимают один дефис (-) в качестве инструкции для использования стандартного ввода.Рассмотрим, учитывая, как вы вызываете вашу примерную команду, следующее:

cat file.txt | grep -Fow "$word" - | wc -l

Это количество экземпляров $word в данном файле.Параметр -F ускоряет поиск, отключая регулярные выражения (поэтому . фактически означает .), -o устанавливает вывод для отображения только совпадений (по одному в строке), а параметр -w требуетграница слова на обеих сторонах слова (поэтому foo будет не совпадать food; уберите этот флаг, чтобы изменить это).wc -l даст вам количество строк, выведенных grep, что является количеством экземпляров $word.(Я не использовал grep -c, потому что это подсчитывает строки со совпадениями, что означает, что foo bar foo baz на строке будет считаться только один раз.)


Если count-words - ваш сценарий, рассмотритеодин из следующих вариантов:

# imply standard input when given insufficient arguments
# or when the only argument is a hyphen
# (requires you to `shift` your options and the query term)
if [ "$#" = "0" ] || [ "$*" = "-" ]; then
  set -- /dev/stdin
fi

# convert hyphen(s) to /dev/stdin within the argument list
FIRST=1
for OPT in "$@"; do
  if [ "$FIRST" = 1 ]; then
    unset FIRST
    set --
  fi
  if [ "$OPT" = "-" ]; then
    OPT="/dev/stdin"
  fi
  set -- "$@" "$OPT"
done

Это позволит вам использовать любой из

  • count-words "$word" < file.txt
  • get-input | count-words "$word"
  • get-input | count-words "$word" -
  • get-input | count-words "$word" /dev/stdin
  • echo "$(get-input)" | count-words "$word"
  • count-words "$word" <<<"list of words as if echoed"
  • count-words "$word" <(get-input)

Последние триявляются ошибками и не будут работать в dash или других более простых /bin/sh программах.Самая последняя команда указывает count-words использовать подстановка процесса для предоставления именованного канала в качестве временного дескриптора файла, в котором хранится вывод get-input.

0 голосов
/ 29 мая 2019

Как отметил Гордон Дэвиссон в комментарии, вы можете использовать специальный файл /dev/stdin, который представляет собой стандартный ввод.

some-command | count-words "$word" /dev/stdin
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...