Wildcards de três pontos

5

Eu tenho uma estrutura de diretórios muito grande de código-fonte que é muito difícil de trabalhar. Eu gostaria de executar uma ferramenta para transformá-lo em uma estrutura semelhante ao Maven que funcione melhor para mim. Quando terminei meu trabalho, eu corro a ferramenta novamente para transformar a estrutura do Maven de volta à estrutura original. Eu estou muito familiarizado com vários shells e sim eu poderia escrever um script contendo centenas de comandos cp. Mas isso será difícil de manter.

Eu quero poder mover ou copiar arquivos usando algo como o curinga de ponto tripla do Perforce que:

Matches all files under the current working directory and all subdirectories. (matches anything, including slashes, and does so across subdirectories)

Meu script, então, contém comandos como:

cp src/.../foobar/.../*.java trusted/src/main/java/.../foobar/.../*.java

A ideia é mover uma subárvore do diretório enquanto mantém a estrutura dessa subárvore.

Alguma idéia?

Estou tendo problemas com a solução de rsync da Gilles. Aqui está um script de teste:

#!/bin/bash

rm -rf source

mkdir -p source/server/src/com/bodhi/foobar/this
mkdir -p source/server/src/com/bodhi/foobar/that
mkdir -p source/server/src/com/bodhi/other

echo "Hello World" > source/server/src/com/bodhi/foobar/this/A.java
echo "Hello World" > source/server/src/com/bodhi/foobar/that/B.java
echo "Hello World" > source/server/src/com/bodhi/other/C.java

rm -rf target
mkdir -p target/foobar/src/main/java

rsync \
  --include='**/foobar/**/*.java' \
  --include='**/foobar/**/' \
  --exclude='*' \
  --prune-empty-dirs \
  source/server/src/ target/foobar/src/main/java/
    
por user1879313 02.02.2015 / 23:33

1 resposta

6

Este coringa existe em ksh93, bash ≥4.3 (≥ 4.0 se não houver link simbólico para diretórios em sua árvore) e zsh. É escrito ** . No ksh93, ele precisa ser ativado primeiro com set -o globstar . No bash, ele precisa ser ativado primeiro com shopt -o globstar .

ls -l src/**/foobar/**/*.java

Isso não serve para fazer a cópia. O destino de cp é um único diretório, cp não faz correspondência de caractere curinga. Você não pode usar um único comando cp para descartar arquivos em locais diferentes.

Você pode usar o rsync . Passe a raiz da árvore de origem e a raiz da árvore de destino e defina as regras de inclusão e exclusão para copiar somente os arquivos desejados e os diretórios que levam a eles. O Rsync irá copiar diretórios vazios também se eles corresponderem ao padrão, você pode fazê-lo excluí-los depois com --prune-empty-dirs .

rsync --include='**/foobar/**/*.java' --include='**/' \
      --exclude='*' --prune-empty-dirs \
      src/ trusted/src/main/java/

Outra ferramenta que você pode usar é pax . Note que pax é o padrão em que é definido pelo POSIX (ao contrário do rsync), mas algumas distribuições do Linux o omitem da instalação padrão (no entanto, ele está sempre disponível como um pacote). A abordagem é semelhante ao rsync: inclua .java arquivos, exclua o restante; a sintaxe é um pouco estranha: você especifica uma substituição de padrão, que pode ser o original para incluir um arquivo e não renomeá-lo, ou um substituto vazio para excluir um arquivo. Os diretórios principais são criados automaticamente no destino, conforme necessário.

pax -rw -s '/\.java$/&/' -s '/.*//' src/* trusted/src/main/java/
    
por 03.02.2015 / 00:00