AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 728390
Accepted
ThePresident
ThePresident
Asked: 2022-12-14 19:50:59 +0800 CST2022-12-14 19:50:59 +0800 CST 2022-12-14 19:50:59 +0800 CST

Alimente arquivos específicos da função do diretório

  • 772

Preciso alimentar um programa com alguns arquivos específicos, na ordem correta e agrupados dois a dois.

Se eu tiver

A_file.txt
B_file.txt
C_file.txt
D_file.txt

Preciso alimentá-lo em um programa para que os arquivos A e B sejam processados ​​​​primeiro, depois C e D e assim por diante. Em essência:

for i in *.txt; do 
   some_program A_file.txt B_file.txt > output_AB
   some_program C_file.txt D_file.txt > output_CD

Eu sei que o acima não faz sentido, mas foi para ilustrar o ponto. Essencialmente, repita todos .txtos arquivos na pasta, mas alimente-os dois de cada vez no programa e, em seguida, passe para os próximos dois.

Olhando para aprender, muito obrigado.

bash
  • 4 4 respostas
  • 439 Views

4 respostas

  • Voted
  1. Best Answer
    Kusalananda
    2022-12-14T23:03:04+08:002022-12-14T23:03:04+08:00
    #!/bin/sh
    
    set -- *_file.txt
    
    until [ "$#" -lt 2 ]; do
        process "$1" "$2" >"output_${1%_file.txt}${2%_file.txt}"
        shift 2
    done
    

    Isso define os parâmetros posicionais para a lista de nomes de arquivo nos quais você está interessado, com base em um padrão de globbing de nome de arquivo correspondente aos nomes na pergunta. Em seguida, ele usa um loop para iterar sobre essa lista até que restem menos de dois nomes na lista ( $#é o comprimento da lista de parâmetros posicionais).

    Em cada iteração, os dois primeiros elementos da lista, $1e $2, são processados ​​e então deslocados para fora da lista usando shift 2.

    A saída do processamento é redirecionada para um arquivo nomeado output_seguido pela concatenação das partes variáveis ​​dos dois nomes de arquivo (o que estiver antes da _file.txtstring estática em cada um).

    Isso pressupõe que os arquivos sejam nomeados de forma que a classificação dos nomes em ordem lexicográfica (o que a expansão do padrão globbing fará) resulte em uma lista de nomes que podem ser emparelhados da maneira mostrada na pergunta.

    • 7
  2. larsks
    2022-12-14T20:26:48+08:002022-12-14T20:26:48+08:00

    Você poderia fazer isso com o xargscomando. Se eu tiver esses arquivos:

    $ ls
    A_file.txt  B_file.txt  C_file.txt  D_file.txt  E_file.txt  F_file.txt  G_file.txt  H_file.txt
    

    Então eu posso processar esses dois ao mesmo tempo assim:

    $ find . -type f | xargs -n2 echo some_program
    some_program ./A_file.txt ./B_file.txt
    some_program ./C_file.txt ./D_file.txt
    some_program ./E_file.txt ./F_file.txt
    some_program ./G_file.txt ./H_file.txt
    

    Aqui estou simplesmente chamando echo, mas é claro que você pode descartar o echoe realmente executar some_program. Isso processará dois arquivos por vez... mas não lida com a geração de um nome de arquivo de saída para cada chamada.

    Se tornarmos um pouco mais elaborado, podemos gerar um arquivo com o nome do primeiro nome de arquivo de entrada:

    find . -type f | xargs -n2 sh -c 'echo some_program $1 $2 > $1.output' --
    

    Isso produzirá o arquivo A_file.txt.outputpara A_file.txte B_file.txt, C_File.txt.outputpara o próximo par e assim por diante. Você pode ficar mais sofisticado com o nome do arquivo de saída aplicando várias transformações; por exemplo, para obter o nome do arquivo que você pediu em sua pergunta, você pode escrever:

    find . -type f | xargs -n2 sh -c 'echo some_program $1 $2 > output_${1:2:1}${2:2:1}' --
    

    Isso gerará nomes de arquivos de saída output_AB, output_CD, etc.

    • 6
  3. Stéphane Chazelas
    2022-12-14T23:39:44+08:002022-12-14T23:39:44+08:00

    Se mudar de bash para zsh for uma opção, então é só:

    for i j ( *.txt(N) ) some_program -- $i $j > output_$i[1]$j[1]
    

    (N)permite nullglob dessa expansão glob para não relatar um erro se não houver correspondência.

    Se houver um número ímpar de arquivos, a última execução será executada com o $jconjunto para a string vazia. Como o deixamos sem aspas no argumento para some_program, isso resultará em nenhum argumento correspondente a ser passado para ele. Substitua por "$j"se preferir que um argumento vazio seja passado para ele nesse caso.

    A *.txtexpansão estará em ordem alfabética; você pode alterar a ordem para o que quiser usando os qualificadores o, Oe/ou n glob .

    Para um número arbitrário de arquivos em cada iteração, em vez de apenas 2:

    files=( *.txt(N) ) n=5
    while (( $#files )) {
      some_program -- $files[1,n] > output_${(Mj[])files[1,n]#?}
      files[1,5]=()
    }
    

    Ou usando zargs:

    autoload -Uz zargs
    process() some_program -- $@ > output_${(Mj[])@#?}
    zargs -rl5 -- *.txt(N) -- process
    

    Em ${(Mj[])array#?}, ${array#?}retiraria o caractere inicial de cada elemento do array, mas com M, o que é Manexado é retornado. O resultado é junificado com nada ( []), então você obtém uma string feita com o primeiro caractere de cada elemento.

    • 5
  4. White Owl
    2022-12-14T20:23:24+08:002022-12-14T20:23:24+08:00

    Despeje a lista de arquivos em uma matriz e leia a partir dela.

    #!/bin/bash
    arr=( *.txt )
    i=0
    while [ $i -lt ${#arr[@]} ];
    do
      echo ${arr[$i]} ${arr[ $[$i+1] ]}
      i=$[$i+2]
    done
    

    Se você tiver um número ímpar de arquivos, a solicitação ${arr[ $[$i+1] ]}fornecerá silenciosamente uma string vazia. Cabe a você decidir o que fazer neste caso.

    • 2

relate perguntas

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve