Любой простой способ сделать для канала цикла, такой как 'ls | grep “.*.7z” | 7z-e {}'

Мне любопытно, который является там функцией/командой для привыкания для канала цикла?

Легко произойти ниже спроса

  1. Вы выполняете возврат команды, который несколько выравнивают
  2. Вы должны обработать каждую строку
  3. передайте каждую строку другой функции/команде

Например:

Вы должны найти, что некоторый путь соответствует 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 

Люди были бы смущены,

  1. почему потребность mv -t (Я имею в виду, через [для канала цикла] можно использовать mv {} some_path ,just как то, что Вы записали без канала),
  2. почему должностное лицо или | xargs является записью таким образом, xargs нужно намного больше опций, но они не на самом деле никакая потребность во многих язык программирования 。
  3. почему я не могу использовать ls ... mv -t path_B {} + , или ls | xargs -0 -I {} mv {} path_B , другими словами, почему это не работает после того, как я изменюсь на другую команду?
  4. Почему я перестал работать когда изменение 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')

Это - очень простой пример с большим количеством дефектов, но он объясняет, что я пытаюсь войти в команду удара.

1
задан 19 March 2020 в 04:51

3 ответа

Я не уверен, что это - прямой ответ на вопрос (существует намного больше чем один вопрос), но я думаю, что Вы просите что-то как:

  • 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 команда).

Этот пример переместится (переименовывают) все файлы рекурсивно, но в архиве появляется привычка структуры каталогов.

2
ответ дан 7 April 2020 в 23:33

Есть ли простой и распространенный способ сделать

Ответ: Нет, каждая команда отличается.


Относительно Ваших вопросов:

  1. Вам не нужно -t, но затем mv будет работать за каждым файлом, который будет намного медленнее. Необходимо закончить Ваш -exec с \; вместо +.

  2. Канал не имеет никакого отношения к a for цикл, канал отправляет stdout от левой стороны канала к stdin на правой стороне. xargs чтения от stdin (или из файла с -a опция) и выполнения команда с аргументами, взятыми от входа.

  3. ls имеет нет -exec опция. ls будет работать с xargs, но не с xargs -0 потому что ls не имеет никакой опции для разграниченного вывода ПУСТОГО УКАЗАТЕЛЯ. Это также, почему Вы не должны использовать ls с каналами вообще (именам файлов позволяют иметь новые строки).

  4. Для mv, -t целевой каталог, в то время как для 7z это - тип архивирования, почему Вы думаете, что это должно работать?

Для меня кажется использованием команд, которые Вы действительно не понимаете. Это не будет работать ни на какой язык программирования или язык сценариев.


Btw: необходимо использовать xargs с -r опция избежать проблем с пустым входом.

1
ответ дан 7 April 2020 в 23:33

Возможно, ваш ответ: xargs -n 1

См. этот пример: 1 единственная строка (цикл создан для gzip):

ls | grep -i '.csv'  | xargs -n 1 gzip

или

ls  | grep -i '.gz'  | xargs -n 1 gunzip
1
ответ дан 10 November 2020 в 13:22

Другие вопросы по тегам:

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