Мне любопытно, который является там функцией/командой для привыкания для канала цикла?
Легко произойти ниже спроса
Например:
Вы должны найти, что некоторый путь соответствует parttern, перемещает каждого в другое место:
# 1.
find path_A -name '*AAA*' -exec mv -t path_B {} +
# 2.
find path_A -name "*AAA*" -print0 | xargs -0 -I {} mv {} path_B
Люди были бы смущены,
-t
(Я имею в виду, через [для канала цикла] можно использовать mv {} some_path
,just как то, что Вы записали без канала),ls ... mv -t path_B {} +
, или ls | xargs -0 -I {} mv {} path_B
, другими словами, почему это не работает после того, как я изменюсь на другую команду?mv
кому: 7z
: find path_A -name '*AAA*' -exec 7z -t {} +
?Примечание: Выше не вопрос, просто примеры!!
Я задал этот вопрос для общего и простого способа справиться для канала цикла. Есть ли простой и распространенный способ сделать:
# 0
command with option (usually you use a command like this)
# 1
command with option [for loop pipe] command with option | command with option
# 2
command with option [for loop pipe] command with option | command with option [for loop pipe] command with option
# 3
....
Таким образом, Вы не должны изменяться command with option
когда Вы используете [для канала цикла]. Это было бы очень удобно для ежедневного использования.
Я поместил весь пример, просто хотят сказать, что нормальный путь сбивает с толку, когда другая команда имеет его собственный стиль для преодоления многострочного входа, этому было бы нужно exec
или xargs
или некоторые еще опции. если у нас есть a for pipe
команда, которая может соединиться два, управляет с опцией. Это было бы очень просто в использовании
Я имею в виду, если Вы используете усовершенствованный язык. Например, Python,
def pipe(x, func, *func_options):
return func(x, *func_options)
def forloop_pipe(x, func, *func_options):
return [func(i, *func_options) for i in x.split('\n')]
def ls(*options)
pass
def mv(*options)
pass
a = ls('*.txt')
b = forloop_pipe(a, mv, '/home')
Это - очень простой пример с большим количеством дефектов, но он объясняет, что я пытаюсь войти в команду удара.
Я не уверен, что это - прямой ответ на вопрос (существует намного больше чем один вопрос), но я думаю, что Вы просите что-то как:
for
цикл с заменой команды илиwhile
цикл с заменой процесса.for
цикл с $(command substitution)
Замена команды позволяет выводу команды заменять саму команду. Мы можем объединить эту функциональность с for
цикл таким образом:
for item in "$(find . -type f)"
do
echo "$item" | tee -a ./"file-list.txt"
done
while
цикл с <(process substitution)
Замена процесса позволяет вводу или выводу процесса быть отнесенным в использование имени файла. Мы можем объединить эту функциональность с while
цикл, справкой встроенного read
, таким образом:
while IFS= read -r item
do
echo "$item" | tee -a ./"file-list.txt"
done < <(find . -type f)
В заключительной части < <(find . -type f)
, первое <
означает stdin в то время как loop
и <(find . -type f)
будет рассматриваться как файл. Больше о конструкции IFS= read -r line
можно читать в этом большом сообщении Stéphane Chazelas.
Можно достигнуть того же как вышеупомянутого при помощи канала вместо замены процесса (но эта опция не предпочтена, потому что это могло вызвать ошибки):
find . -type f | while IFS= read -r file
do
echo "$file" | tee -a ./"file-list.txt"
done
Далее мы можем передать по каналу или перенаправить вывод цикла к другой команде или функции:
while IFS= read -r -d '' item; do
# Compose the name of the new file
DIR="$(dirname "${item}")"
FILE_NAME="$(basename "${item}")"
NEW_FILE_NAME="new-${FILE_NAME}"
# move the file and suppress the potential output
# of the 'mv' command by redirecting it to a log file
mv "${item}" "${DIR}/${NEW_FILE_NAME}" >>/tmp/mv-loop.log 2>&1
# output the name of the new file in order to be processed
# by the next (piped) command
printf '%b' "${DIR}/${NEW_FILE_NAME}"'\0'
done < <(find . -type f -print0) | xargs -0 -I{} 7z a -t7z "the_archive_name.7z" {}
Отметьте в вышеупомянутом примере, пустые разделители используются везде:
find . -print0
, IFS= read -r -d '' item
- ссылка,printf '%b' a'\0'b
- ссылка,xargs -0
(в этом случае нам на самом деле не нужно -I{}
и {}
в xargs
команда).Этот пример переместится (переименовывают) все файлы рекурсивно, но в архиве появляется привычка структуры каталогов.
Есть ли простой и распространенный способ сделать
Ответ: Нет, каждая команда отличается.
Относительно Ваших вопросов:
Вам не нужно -t
, но затем mv
будет работать за каждым файлом, который будет намного медленнее. Необходимо закончить Ваш -exec
с \;
вместо +
.
Канал не имеет никакого отношения к a for
цикл, канал отправляет stdout от левой стороны канала к stdin на правой стороне. xargs
чтения от stdin (или из файла с -a
опция) и выполнения команда с аргументами, взятыми от входа.
ls
имеет нет -exec
опция. ls
будет работать с xargs
, но не с xargs -0
потому что ls
не имеет никакой опции для разграниченного вывода ПУСТОГО УКАЗАТЕЛЯ. Это также, почему Вы не должны использовать ls
с каналами вообще (именам файлов позволяют иметь новые строки).
Для mv
, -t
целевой каталог, в то время как для 7z
это - тип архивирования, почему Вы думаете, что это должно работать?
Для меня кажется использованием команд, которые Вы действительно не понимаете. Это не будет работать ни на какой язык программирования или язык сценариев.
Btw: необходимо использовать xargs
с -r
опция избежать проблем с пустым входом.
Возможно, ваш ответ: xargs -n 1
См. этот пример: 1 единственная строка (цикл создан для gzip):
ls | grep -i '.csv' | xargs -n 1 gzip
или
ls | grep -i '.gz' | xargs -n 1 gunzip