Значение col1
13 символьных строк ma${token}jid
. Когда Вы пишете echo ${col1}
без кавычек, замен оболочки ${col1}
значением переменной, затем выполняет разделение слова (т.е. разбивание значение в отдельные слова в $IFS
символы) и поколение имени файла (т.е. globbing). Значения переменных рекурсивно не расширены с помощью синтаксиса оболочки. Если Вы используете двойные кавычки вокруг подстановки переменных (который необходимо сделать, если у Вас нет серьезного основания не к), "$col1"
прямо расширяется до значения col1
.
Если Ваши строки являются достаточно ручными (т.е. не содержите специальные символы оболочки, кроме ${token}
то, что Вы хотите занять место), затем можно создать строку из $col1
то, что Вы оцениваете как отрывок оболочки. В Вашем примере следующая строка распечатала бы ma12345678jid
:
eval "echo $col1"
С другой стороны, замените маркер ${token}
требуемым значением. Можно сделать это со строковой заменой в ударе:
while read -r col1 col2 col3; do
echo "${col1//'${token}'/$token}"
echo "${col2}"
echo "${col3}"
echo "********************************"
done <input.txt
Можно также сделать это с awk
, как пред - или выполняющий последующую обработку шаг (в зависимости от того, хотите ли Вы выполнить замену в других столбцах также).
<input.txt awk -v repl="$token" '{gsub(/\${token}/, repl); print}' |
while read …
Можно выполнить замену с sed
, но только если Вы уверены что ни один из символов &\/
и новая строка появляется в тексте замены $token
(можно изменить символ разделителя от /
к чему-то еще, если существует другой символ, который Вы уверены, не появляется в $token
).
<input.txt sed -e "s/\\\${token}/$token/" |
while read …
Сделайте это вместо этого:
find . -type f -iname '*.xml' -o -iname '*.png'\
-o -iname '*.jpeg' -o -iname '*.gif' -delete
Вы могли также использовать регулярные выражения:
find . -type f -iregex '.*\.\(xml\|png\|jpeg\|gif\)$' -delete
Существует в основном 4 пути, которыми можно приблизиться, это использование задач находят.
-delete
$ find . -type f -iname '*.xml' -o -iname '*.png'\
-o -iname '*.jpeg' -o -iname '*.gif' -delete
Поскольку другие упомянули в этом Вопросы и ответы, этот метод является самым быстрым и наименее интенсивно использующим ресурсы. Заключение в кавычки от находки документы онлайн:
10.1.6 Используя '-delete' действие
Самый эффективный и безопасный метод решения этой проблемы должен использовать '-delete' действие:
find /var/tmp/stuff -mtime +90 -delete
Эта альтернатива более эффективна, чем любой из
-exec' or
- execdir' действия, так как это полностью избегает издержек разветвления нового процесса и использованияexec' to run
/bin/rm'. Это также обычно более эффективно, чемxargs' for the same reason. The file deletion is performed from the directory containing the entry to be deleted, so the
- удалите' действие, имеет те же преимущества безопасности, как '-execdir' действие имеет.'-Delete' действие был представлен семейством BSD операционных систем.
Примечание: Одна вещь иметь в виду с этим подходом, использованием -delete
подразумевает также переключатель -depth
. Что это означает? Вот пример как -delete
может записать Вас, если Вы не осторожны.
Например, скажите, что у меня есть рабочий каталог подверсии, где я хочу очистить некоторые файлы, но оставить его .svn подкаталоги неповрежденными. Я мог бы использовать следующую команду для выполнения этого:
$ find . -not "(" -name .svn -type d -prune ")" -type f -print
./a.txt
Но потому что -delete
включает a -depth
переключатель, файлы, которые на самом деле добрались бы, имел дело с:
$ find . -not "(" -name .svn -type d -prune ")" -type f -print -depth
./.svn/all-wcprops
./.svn/entries
./.svn/format
./.svn/text-base/a.txt.svn-base
./a.txt
Поэтому при использовании -delete
, заботу нужно соблюдать.
-exec command {} +
$ find . -type f -iname '*.xml' -o -iname '*.png'\
-o -iname '*.jpeg' -o -iname '*.gif' -exec rm {} \+
По сравнению с -delete
метод, это наиболее вероятно следующий наилучший вариант, с точки зрения производительности и мобильности через Unixes. -exec ... {} +
нотация работает следующим образом:
из страницы справочника находки
Этот вариант - исполнительное действие выполняет указанную команду на выбранных файлах, но командная строка создается путем добавления каждого выбранного имени файла в конце; общее количество вызовов команды будет намного меньше, чем количество подобранных файлов. Командная строка создается почти таким же способом, которым xargs создает свои командные строки. Только один экземпляр '{}' позволяется в рамках команды. Команда выполняется в начальном каталоге.
Таким образом, в действительности этот метод работает подобный xargs
, но не имея необходимость переходить через обручи передачи вывода находки через канал к xargs
.
xargs
$ find . -type f -iname '*.xml' -o -iname '*.png'\
-o -iname '*.jpeg' -o -iname '*.gif' -print0 | xargs -0 rm -f
find ... -print0
создаст список файлов, соответствующих указанным критериям. Этот список затем передается через канал xargs
. -print0
переключатель помещает символ ASCII NUL, поскольку разделитель между каждым результатом находит. -0
включить xargs
заставляет его предположить, что файлы, передаваемые в, разделяются символами ASCII NUL.
По сравнению с методами № 1 и № 2, у этого будет подобная производительность к № 2, однако -print0
переключатель универсально не поддерживается через весь Unixes.
-exec command {} \;
$ find . -type f -iname '*.xml' -o -iname '*.png'\
-o -iname '*.jpeg' -o -iname '*.gif' | exec rm -f {} \;
По сравнению с первыми 3 методами это наименее производительно. Это буквально звонит rm
команда для каждого отдельного файла, что find
команда находит.
Одна вещь, которая не могла бы быть настолько очевидной при использовании любого из вышеупомянутых методов, состоит в том, что некоторые методы более безопасны, чем другие. Вы, вероятно, говорите себе... безопасность?.. что? Вот пример.
Примите свой корень, и Вы выполняете следующую команду:
$ find /var/tmp/somedir -type f -exec rm {} \;
Без ведома Вам, кто-то злонамеренно создал ссылку на /etc
каталог под /var/tmp/somedir
. Когда вышеупомянутая команда работает, /etc
каталог будет также удален. Эта проблема существует с любым из методов для удаления файлов, за исключением -delete
опция (метод № 1).
Самый быстрый и самый безопасный способ удалить файлы с помощью находки состоит в том, чтобы использовать -delete
. Используя xargs -0
может быть подобным в производительности, но это не столь безопасно. -delete
действие не является абсолютно портативным. Самая эффективная портативная альтернатива -exec ... +
, но это небезопасно и не поддерживается версиями GNU findutils до 4.2.12.
find
не звонит rm
утилита, когда Вы используете -delete
, это делает удаление отдельно, таким образом, Ваша рекомендация звонить xargs
поскольку эффективность является поддельной (и даже немного контрпродуктивной). Вдобавок ко всему, не звоните find … | xargs somecommand
как xargs
ожидает его вход, заключенный в кавычки в формате это find
не производит. Использовать find … -print0 | xargs -0 somecommand
или просто забудьте о xargs
и используйте find … -exec somecommand {} +
который имеет тот же эффект группировки. @EvanTeitelman Резервируют Ваш upvotes для ответов, которые полезны.
– Gilles 'SO- stop being evil'
24.04.2013, 03:47
Существует небольшая погрешность в ответ slm.
NOTE & Disclamer: это должно быть комментарием к ответу slm, но право теперь я еще не могу сделать комментариев.
Пример "кто-то злонамеренно создал ссылку", данную к Дополнительным соображениям вокруг безопасности, не полностью точно и о жестких ссылках Unix и для гибких ссылок Unix.
Для понимания различия между этими двумя, посмотрите Жесткую ссылку и Символьные ссылки в Unix или погуглите его.
Для гибких ссылок (наиболее используемый тип так или иначе) оба GNU find
и BDS find
не переходит по символьным ссылкам, если не используется определенное -L
отметьте для принуждения символьной ссылки после. [Посмотрите man find
]
Таким образом, этим примером, вероятно, не будет prolem, если Вы не вызовете find
следовать за гибкими ссылками с помощью -L
флаг. Это - опасный выбор, так или иначе.
Для жестких ссылок, find
перейдет по ссылке в другой файл, но обратите внимание на то, что трудно соединение с другим каталогом, "вероятно, перестанет работать" как посмотрите в man ln
для GNU ln
:
-d, -F, --directory
allow the superuser to attempt to hard link directories (note: will probably
fail due to system restrictions, even for the superuser)
Таким образом, вероятно, невозможно создать жесткую ссылку на каталог во-первых и find
не будет иметь ничего для следования.
Обратите внимание что некоторый BDS ln
реализация не имеет a -d
опция вообще.
-exec rm
, существует все еще состояние состязания, поскольку можно заменить каталог в /var/tmp
промежуточный время find
списки это и rm
запускается и звонит unlink
системный вызов. (Нестандартный) -delete
опция решает это при помощи fchdir
и unlinkat
проверка находит, удаляет то, что она думает, что удаляет.
– Stéphane Chazelas
10.05.2013, 12:58
-mtime +730
. Время указано в днях. Посмотритеfind
страница справочника (man find
) для получения дополнительной информации. Некоторые оболочки допускают замену оцененных выражений, которые могут быть полезными в ситуациях как они.-mtime +$(( 365 * 2 ))
. – 22.04.2013, 23:58find . -mtime +730 -type f -iname '*.xml' -o -iname '*.png' -o -iname '*.jpeg' -o -iname '*.gif' -delete
илиfind . -mtime +730
? фейспалм – 23.04.2013, 00:26-print
опция к Вашей команде для наблюдения, что файлыfind
обнаруживает. Вы могли отправить полную команду, которую Вы используете? Включите его в обратные галочки ('') так, чтобы это было похожеthis
. – 24.04.2013, 02:59