Как использовать xargs с ed?

Я хочу рекурсивно заменять строки внутри папки, и я решил использовать Perl. Я хотел бы посмотреть, есть ли решение, которое требует меньшей зависимости и работы на разных платформах.

Для списка файлов я могу использовать что угодно от ls до find до ag, rg. Позвольте мне продемонстрировать мою проблему с ls.

ls | xargs -I '{}' ed -s {} <<< $'='

Я получу это:

Is a directory newline appended =: No such file or directory

Поскольку канал используется для передачи имен файлов в xargs, а потоки (здесь-строка), похоже, не работают (Как можно использовать heredocs с xargs?). Интересно, можно ли использовать xargs с ed.

Меня беспокоит кроссплатформенность, и на самом деле эта команда будет помещена внутри package.json для npm run global_replace. Нам интересно, есть ли другие решения, кроме введения gulp-replace и gulp только для этой задачи.


person Sunny Pun    schedule 09.11.2018    source источник
comment
Какую команду вы пытаетесь запустить в ed? $'=' сокращается оболочкой до = (кавычки ANSI-C) и печатает номер текущей строки, которая является последней.   -  person Benjamin W.    schedule 09.11.2018
comment
@БенджаминВ. Извините за плохой пример. Другой может быть $'2,5d\nw', который должен удалить эти строки и сохранить. Моя цель состояла в том, чтобы продемонстрировать, что herestring не работает.   -  person Sunny Pun    schedule 09.11.2018


Ответы (2)


Попробуйте это решение:

find . -name "*" | xargs sed -i 's/regex/replacestring/g'
person Vinod Kumar    schedule 09.11.2018
comment
Спасибо! Когда-то я думал, что sed будет достаточно независимым от платформы. Однако sed отличался для естественной установки Linux и MacOS, и что даже с sed -i '' '...' есть недопустимые байты, для которых требуется LC_ALL=C, который преобразует окончания строк. Надеюсь, что ed будет вести себя лучше. - person Sunny Pun; 09.11.2018

После некоторого исследования использование herestring не является полностью невозможным:

find ... | xargs -0 -I{} sh -c 'ed -s "$1" <<< '"$',s/foo/bar/g\nw'" -- {}

А в package.json мне нужно экранировать каждое ", так что теперь мы можем запустить npm run replace. Код выхода будет иметь статус 1, и это выглядит не очень хорошо, хотя и работает.

Большое спасибо @Benjamin.W за помощь в комментариях!

person Sunny Pun    schedule 09.11.2018
comment
Вы можете переместить части аргумента в sh -c, чтобы они заключались в двойные кавычки, а остальные — в одинарные, например: sh -c 'ed -s "$1" <<< '"$',s/foo/bar/g\nw'". Обязательно цитируйте $1, иначе все преимущества -print0 и xargs -0 снова будут потеряны. - person Benjamin W.; 09.11.2018
comment
добавление новой строки указывает, что в файле не было новой строки в последней строке, и ed добавил ее. Некоторые редакторы создают такие файлы, но согласно POSIX они не должны этого делать. - person Benjamin W.; 09.11.2018