экранирование имени файла является результатом команды grep

В чем проблема:

for ((i=1;i<=24;i++)) ; do
    cd PKA${i}/timestep_size/v_0.001/250eV
    ../ovitos silica_defects.py
    cd $OLDPWD
done
1
28.07.2016, 07:30
1 ответ

In

ls $(grep file file.txt)

Вы неправильно используете оператор split+glob, и именно в этом кроется ваша проблема. Вы не хотите вставлять кавычки в вывод grep, поскольку этот вывод не интерпретируется как shell-код (к счастью!), но вам нужно настроить свой оператор split+glob.

Здесь

  1. Вам не нужна часть glob (расширение слов *, например, в список файлов в текущем каталоге), поэтому вам нужно отключить ее с помощью:

    set -o noglob
    
  2. Вы хотите разделить вывод grep только по символам новой строки (это по-прежнему означает, что имена ваших файлов не могут содержать символов новой строки, но это ограничение формата вашего file.txt файла) с помощью:

    IFS='
    '
    

    or

    IFS=$'\n'
    

    в некоторых оболочках.

И тогда вы можете вызвать свой оператор split+glob (оставив $(...) без кавычек), но скорее:

ls -d -- $(grep file files.txt)

Этот оператор split+glob - ошибка, унаследованная от оболочки Bourne. В современных оболочках есть другие способы разделить некоторый текст на список его строк.

В zsh:

ls -d -- ${(f)"$(grep file files.txt)"}

The, f флаг расширения параметров для разбиения на newline (linefeed), сокращенно ps:\n:' (s:string: используется для разбиения на произвольные строки, p для понимания управляющих последовательностей типа \n в этой строке). Мы цитируем $(...) для отключения оператора split+glob, хотя в случае zsh есть только часть split (без glob).

С bash:

readarray -t files < <(grep file files.txt)
ls -d -- "${files[@]}"

Где вы можете захотеть вставить кавычки, так это при использовании xargs, поскольку формат ввода xargs - это пустой разделенный список, где разделители могут быть заключены в одинарную, двойную кавычку или обратную косую черту (но по-другому, чем это делается в shell).

Так что вы можете сделать:

 sed '
   s/"/"\\""/; # escape the " characters themselves
   s/^/"/;s/$/"/; # insert one at the beginning and one at the end
 ' < files.txt | xargs ls -d --
4
27.01.2020, 23:19

Теги

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