В чем проблема:
for ((i=1;i<=24;i++)) ; do
cd PKA${i}/timestep_size/v_0.001/250eV
../ovitos silica_defects.py
cd $OLDPWD
done
In
ls $(grep file file.txt)
Вы неправильно используете оператор split+glob, и именно в этом кроется ваша проблема. Вы не хотите вставлять кавычки в вывод grep
, поскольку этот вывод не интерпретируется как shell-код (к счастью!), но вам нужно настроить свой оператор split+glob.
Здесь
Вам не нужна часть glob (расширение слов *
, например, в список файлов в текущем каталоге), поэтому вам нужно отключить ее с помощью:
set -o noglob
Вы хотите разделить вывод 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 --