Обычно bash
не заботится о том, читает ли он свои команды из файла (как в bash foo
) или из STDIN (как в bash
apt-get
), которая сама хочет спросить пользователя и использует для этого STDIN.
Поэтому происходят странные вещи: bash считывает команды из STDIN и выполняет их одну за другой. Теперь одна из команд читает из STDIN и, ну, читает следующую строку файла. После этого bash читает следующую строку из STDIN и поэтому пропускает одну команду, уже прочитанную другой командой.
Этот небольшой сценарий продемонстрирует, что происходит:
echo "hello"
read -p "how do you do? "
echo "I understand"
echo "you are '$REPLY'."
echo "bye"
Сохраните его в файл и сначала запустите как bash -x foo
, а затем как bash -x
То же самое произойдет и в вашем примере.
Одним из решений было бы использовать подстановку процесса:
bash -x <(cat foo)
или, в вашем случае, просто:
bash <(curl -s0 https://myserver.com/install.sh)
Некоторые примечания:
Когда какой-либо сценарий оболочки делает странные вещи, используйте bash -x
, чтобы увидеть что происходит.
Написание cat foo | ...
известен как Бесполезное использование кота . Просто используйте вместо этого перенаправление.
sed
решение. Ищет дефис, за которым следуют 3 символа, за которыми следует.mp4, за которым следует конец строки ($ ), и ничего не заменяет.
Прочитать "file", записать более короткие имена в файл "newfile".
sed 's/-...\.mp4$//g' file >newfile
или отредактируйте «файл» на месте
sed -i 's/-...\.mp4$//g' file
$ sed 's/-[^-]*\.mp4$//' file
55363642b-b13218-4cb0-8334-546565346
gfdggwg-e1321-4qwe-9ewq-de32155139d8
Выражение sed
s/-[^-]*\.mp4$//
представляет собой замену, которая соответствует тире, за которым следует любое количество не -тире, точку и строкуmp4
(в самом конце строки ). Соответствующий текст удаляется.
Чтобы внести изменения в -, используйте флаг -i
для sed
(, но запустите без предварительного запуска, чтобы убедиться, что результат правильный):
sed -i 's/-[^-]*\.mp4$//' file
Если бы это были имена файлов, я бы вместо этого перебирал фактические файлы:
for mp4file in *.mp4; do
printf 'The truncated name is "%s"\n' "${mp4file%-*.mp4}"
done
Подстановка параметра ${mp4file%-*.mp4}
будет расширена до имени файла, в конце которого будет удалена самая короткая строка, соответствующая -*.mp4
.
Использованиеawk
:
awk -F- -vOFS=- 'NF{NF-=1};1' file
Это разграничит каждую строку с помощью -
и удалит последнее поле, а затем напечатает оставшиеся поля с добавленным тире -.