Copiando arquivos em um pipeline usando o shellscript cygwin bash

2

Eu preciso selecionar determinados arquivos em um diretório e copiá-los para outro diretório usando um script cygwin, mas não consigo obter a sintaxe da cópia. ou seja,

para i em cat boards Faz ls -t $ work | grep ^ $ i | cp .............

Se eu correr apenas com o grep, ele listará todos os arquivos que eu quero, mas não sei como obter isso no cp cmnd.

Muito tempo desde que fiz nada disso, mas parece que há uma variável automática contendo a entrada de stdin. Qualquer ajuda apreciada.

    
por Stumac 22.09.2017 / 19:00

2 respostas

1

Parece que você está procurando por xargs .

destination="/path/to/folder"
for i in $(cat boards)
do 
     ls -t $work | grep ^$i | xargs -Isource cp source /path/to/destination
done

Execute um loop for usando a variável i preenchida com os resultados de cat boards ( $() gera um processo).

xargs -Isource recebe a saída de grep ^$i e a alimenta em cp na source posição de cp source /path/to/destination . Na página do manual:

-I replace-str Replace occurrences of replace-str in the initial-arguments with names read from standard input.

Espero que isso seja o que você estava procurando.

    
por 22.09.2017 / 20:09
1

Eu estou supondo que você quer que todos os arquivos copiados acabem no mesmo lugar.

Parece que você quer que todos os arquivos em / path / to / $ funcionem onde o nome do arquivo começa com uma linha do arquivo de placas a ser copiada para algum destino.

por exemplo, dado

$ cat boards
start1
start2
$ ls $work
start1.txt
start1.jpg
start2.txt
start2.jpg
start3.txt
$

você deseja que start1.txt, start1.jpg, start2.txt e start2.jpg sejam copiados para algum lugar, mas não para start3.txt.

Não use xargs: é uma ferramenta fantástica, mas causará problemas se algum dos seus arquivos ou "padrões de pesquisa" tiverem espaços ou caracteres glob (por exemplo, "*").

Em vez disso, use uma ferramenta que espera um padrão de pesquisa, encontre .

cat boards | while read pattern
find $work -name "${pattern}*" -exec cp {} /path/to/destination +
done

Isso será lido em cada linha de boards como um padrão de pesquisa. find procurará no diretório $work para localizar arquivos (e pastas!) que correspondam a ${pattern}* ; cada item encontrado (arquivo ou pasta) será passado para cp como um parâmetro com escape adequado (no {} spot), e fará xargs - como a minimização do número de processos cp iniciados devido a o + (se você quisesse exatamente um processo por item encontrado, você usaria um ; - certifique-se de escapar corretamente, no entanto).

find tem um rico conjunto de filtros que você pode aplicar para restringir sua pesquisa. De particular interesse é a opção -type f que limitará os resultados ao arquivo.

Observe que o comando cp pode falhar se houver pastas na lista de argumentos transmitida de find ; usar o filtro -type f impedirá isso.

Note também que o comando cp irá "achatar" o diretório de saída - se $work tiver subdiretórios que possuam arquivos correspondentes, esses arquivos serão copiados diretamente para /path/to/destination . Se você deseja copiar apenas arquivos no nível superior de $work , o filtro -maxdepth (provavelmente com um valor de 1: -maxdepth 1 ) impedirá que find recorrer muito no sistema de arquivos.

Note também que find faz distinção entre maiúsculas e minúsculas. Se você não quiser, use -iname em vez de -name para fazer uma pesquisa sem distinção entre maiúsculas e minúsculas.

Se houver qualquer outro parâmetro de linha de comando que você deseja atribuir a cp , basta colocá-lo na frente do {} (por exemplo, cp -r {} para copiar diretórios que correspondam ao padrão de pesquisa).

    
por 22.09.2017 / 23:22

Tags