Как передать аргумент в sed без входных файлов. СЭД находится в одинарной кавычке и уже содержит канал.
git filter-branch -f --index-filter \
'git ls-files -s | sed -i "s-\t\"*-&dirname/-" |
GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
git update-index --index-info &&
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
Приведенный выше код отлично работает, если имя каталога жестко запрограммировано. Но мне нужно передать имя каталога из аргументов командной строки в скрипт. Я пытаюсь, как показано ниже, но не повезло.
'set subdir=$folder;git ls-files -s | sed -i "s-\t\"*-&$subdir/-" |
Sed говорит, что входной файл отсутствует. Я не могу напрямую передать входной файл в sed. Я вижу ошибку, как показано ниже.
Rewrite 9c86de42b7f3228e3d45a278c8caf7e24c8e55cf (1/2) (0 seconds passed, remaining 0 predicted)
sed: no input files
Вы используете sed -i
, который редактирует свои аргументы командной строки (которые являются именами файлов) на месте. Однако вы читаете со стандартного ввода и не указали никаких аргументов командной строки. Если вы хотите просто отфильтровать стандартный ввод, опустите -i
из команды sed
.
Значение из $folder не передается должным образом, и, следовательно, команда git дает сбой. Если значение $folder жестко закодировано в sed, команда git работает.
Принято как ответ. Удаление опции «-i» в sed игнорирует входные данные. Кроме того, одиночная кавычка и двойная кавычка $folder делают свое дело, как указывает torek.
Здесь у вас есть два варианта. Вы можете либо оценить $subdir
, чтобы создать фиксированную команду sed
, которую затем установите в качестве фильтра; или вы можете оценить переменную во фрагменте оболочки, который будет вызываться git filter-branch
.
Чтобы понять последнее, поймите, что ваша строка --index-filter
становится обычная переменная оболочки:
--index-filter)
filter_index = "$OPTARG"
;;
который тогда перешел на eval
:
eval "$filter_index" < /dev/null ||
die "index filter failed: $filter_index"
eval
означает, что выражение в $filter_index
, установленное из вашего аргумента --index-filter
, имеет доступ ко всем переменным оболочки и функциям в скрипт ветки фильтра. К сожалению, ни одна из его переменных частный не содержит нужного вам выражения, но вы можете получить доступ к его переменным окружающая обстановка, что означает, что вы можете поместить значение в переменную среды. Другими словами, вы можете поставить subdir=<whatever>
как окружающая обстановка к исходному выражению.
В любом случае, как bk2204 ответил, вам нужно убрать опцию -i
. Кроме того, некоторые версии sed
не принимают \t
в качестве символа табуляции (вероятно, у вас есть, просто имейте в виду).
Чтобы расширить переменную ранее, просто сделайте это. Например:
... --index-filter \
'git ls-files -s | sed "s-\t\"*-&'$folder'/-" | ...
(Я сам удалил -i
здесь). Обратите внимание, как это выходит из одинарных кавычек, расширяется $folder
, а затем снова входит в одинарные кавычки. Если $folder
может содержать пробелы, обязательно используйте двойные кавычки, расширяя его здесь:
... --index-filter \
'git ls-files -s | sed "s-\t\"*-&'"$folder"'/-" | ...
Вложение кавычек здесь довольно сложно: содержимое одинарных кавычек представляет собой одну большую строку, предоставленную в качестве аргумента, который устанавливает переменную $filter_index
внутри скрипта filter-branch
. eval
запускает его через второй проход оценки, разбивая его на конвейер (git ls-files
, передает в sed
, передает в git update-index
) и запускает различные команды, каждый из которых перенаправляет свой стандартный ввод на /dev/null
.
Я попробовал последнее, и это сработало. Это полный ответ, и он сэкономил много времени. Кажется, что eval решает передачу аргументов при вложении. Я попробую при дальнейшем обновлении сценария.
Я назначил аргументы строки cmd переменной папке и использовал ее, как показано ниже. Но видит ошибку. 'git ls-файлы -s | sed "s-\t\"-&$folder/-" | Переписать d97350e369514528ea545e200cf1481cdae3ac61 (1/2) (прошло 0 секунд, осталось 0 предсказанных) Игнорирование пути /index.js mv: cannot stat '/home/apurb/git_poc/poc-apollo-server/.git -rewrite/t/../index.new': Нет такого файла или фильтра индекса каталога не удалось: git ls-files -s | sed "s-\t\"-&$folder/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new \ git update-index --index-info && mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"