xargs с двумя командами - mkdir и sed

585
diego9403

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

cut -d ';' -f 1 tmp1 | tr '.' '/' | xargs -I % bash -c 'mkdir -p %; sed 's/$/\/version/'% > output' 

И у меня есть ошибка:

sed: -e expression #1, char 6: unknown option to `s' 

Вы знаете, что я делаю не так?

1

1 ответ на вопрос

1
Jay jargot

Произошла ошибка, потому что вы используете много '. В частности s/$/\/version/, за пределами одной цитаты.

sedлибо работает с файлом, либо со стандартным вводом. Он не может изменить строку, переданную в качестве параметра. printfвстроенная команда может быть использована для добавления /version.

Примечания:

  • Для каждой строки, прочитанной из tmp1файла, извлекается одно имя, поэтому имена не содержат \n.
  • в соответствии с использованием cutи tr, результирующие каталоги не будут содержать .ни ;их имен, ни символов.

То, что вы пытаетесь достичь, это:

cut -d ';' -f 1 tmp1 | tr '.' '/' | xargs -I % bash -c 'mkdir -p "%" ; printf "%s/version/\n" "%"' > output 

Обратите внимание, что специальные символы в именах нарушают вышеприведенную командную строку: например, '(одинарные кавычки).

cutи trможет быть заменен только одним, awkкоторый xargs -0может использоваться для безопасной обработки имен (разделенных нулевым символом).

Попробуйте эту безопасную версию:

awk -F\; '' tmp1 | xargs -0 bash -c 'for f; do mkdir -p "$";printf "%s/version\n" "$";done' arg0dummy > output 

awk сценарий:

  • -F\;определяется ;как разделитель полей, так же $1как и первое поле (до ;)
  • gsubиспользуется для замены .на/
  • printfиспользуется для печати результата и вставки окончательного \0(нулевого) символа.

xargs:

  • -0: Входные элементы заканчиваются нулевым символом вместо пробела, и кавычки и обратный слеш не являются специальными (каждый символ воспринимается буквально). Отключает конец строки файла, который обрабатывается как любой другой аргумент. Полезно, когда элементы ввода могут содержать пробелы, кавычки или обратную косую черту.

bash -c ...:

  • arg0dummy: не используется, но является обязательным; см man bash.