Как я могу прочитать из именованного канала построчно и выйти?

Перл:

perl -lpe 'if (/^DL1 :/) {s/,?xyz\@kk\.com//; s/: \K,//}' file

АВК:

awk '/^DL1 :/ {sub(/,?xyz@kk\.com/,"");sub(":,",": ")} 1' file

сед:

sed -E '/^DL1 :/ s/,?cde@kk.com//; /^DL1 :/ s/:,/: /' file

Примечание:

Возможно, это не самые лучшие инструменты для манипулирования тем, что по сути является разновидностью CSV-файла. Я предлагаю вам добавить больше контекста о том, откуда берутся данные и их предполагаемое использование.

0
01.04.2021, 15:00
2 ответа

Я бы предложил несколько альтернатив, потому что:

  • Судя по сценарию в вашем вопросе, FIFO на самом деле не нужен;
  • в принципе, поскольку вы используете Bash, вы можете использовать символ NUL в качестве разделителя (единственный байт, который не разрешен в пути к файлу POSIX ); однако, к сожалению, fzfне работает с именами файлов, содержащими символы новой строки;
  • чтение из файла в /tmpможет представлять собой серьезную проблему безопасности :если кто-то другой создал/tmp/fuzzy-opener(как обычный файл ), ваш скрипт с радостью применит openк его содержимому (хотя, в некоторых системах открытие не принадлежащего -файла в словесном -записываемом каталоге с использованием exec 3<>вызовет ошибку).

Вы можете использовать:

function open {
  while IFS= read -r -d '' file
  do
    echo "$file"    # Replace with the actual open action
  done
}

alacritty -e sh -c 'fzf -m --disabled --print0 >&3' 3>&1 | open

, который можно сделать переносимым, удалив -d ''и--print0(ничего не потеряв, учитывая вышеупомянутое ограничениеfzf); или, используя массив для хранения выбранных имен файлов:

function open {
  for file
  do
    echo "$file"    # Replace with the actual open action
  done
}

mapfile -t -d '' toopen < <(alacritty -e sh -c 'fzf -m --print0 >&3' 3>&1) &&
  open "${toopen[@]}"

В обоих случаях главное заключается в том, что вывод fzfперенаправляется на новый дескриптор файла, полученный дублированием конца записи канала и, таким образом, связанный с командой чтения.

2
28.04.2021, 22:54

Конвейер покажет EOF (возврат из read()с нулевыми прочитанными байтами ), если сторона записи закрыта. Но я думаю, что происходит то, что поскольку <>открывает канал в режиме чтения -записи, у канала всегда есть писатель, а оболочка держит дескриптор файла открытым.

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

alacritty -e sh -c "fzf -m >$FIFO" && open < "$FIFO"

Или, точнее:

alacritty -e sh -c 'fzf -m >"$1"' sh "$FIFO" && open < "$FIFO"

Здесь я предполагаю, что конструкция в вопросе работает иначе, как и должно быть, если alacritty порождает терминал в фоновом режиме и немедленно завершает работу. Если это не так, вам понадобится что-то вроде alacritty -e sh... & open < "$FIFO"для одновременного запуска обеих частей.

3
28.04.2021, 22:54

Теги

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