movendo diretórios após grep

movendo diretórios após grep

Emiti o próximo comando para mover alguns diretórios para a pasta "build_tools", porém o resultado não foi o que eu esperava.

ls -l | grep 2014-03 | awk '{if ($8!=build_tools) print $8}' | xargs mkdir build_tools/{} && mv {}/ build_tools/{}/

Ele moveu a pasta "build_tools" para uma das pastas geradas pelo awk (zlib) junto com o restante dos diretórios e então ficou preso com esta mensagem:

mkdir: no se puede crear el directorio «zlib»: El archivo ya existe

Alguém pode esclarecer qual é o meu erro?

EDITAR 1:

A saída de ls -l me dá:

drwxr-xr-x  3 poissonbreaker poissonbreaker     4096 2011-05-02 09:58 antlr3.2
-rw-r--r--  1 poissonbreaker poissonbreaker   318588 2011-05-17 16:21 AppFramework-1.03.jar
-rw-r--r--  1 poissonbreaker poissonbreaker        0 2014-03-04 09:53 awk
drwxr-xr-x  4 poissonbreaker poissonbreaker     4096 2013-01-11 23:13 clutter-sharp
-rw-r--r--  1 poissonbreaker poissonbreaker      429 2014-01-14 09:49 Dependencias

Eu só quero pegar os arquivos com o campo de data ($6) correspondente a 2014-03, é por isso que faço um grep simples como (Nenhum arquivo no diretório tem como nome de arquivo este padrão):

ls -l  | grep 2014-03 

O que rende:

-rw-r--r--  1 poissonbreaker poissonbreaker        0 2014-03-04 09:53 awk
-rw-r--r--  1 poissonbreaker poissonbreaker      429 2014-01-14 09:49 Dependencias

Então eu recebo o campo de nome de arquivo ($ 8) de cada arquivo através do awk para finalmente ser movido para a pasta build_tools (neste ponto eu sei qual foi o meu erro - a pasta build_tools também foi criada nesta data: S). Vou deixar essa pergunta aqui, caso algumas partes sejam úteis para alguém.

EDIT 2: mudei a expressão awk para:

awk '{if ($8!=build_tools) print $8}'

para que faça sentido.

Responder1

Presumo que você tenha GNU find. Se você deseja mover arquivos ou diretórios modificados dentro de um determinado período de tempo (por exemplo, março de 2014), faça o seguinte:

find . -maxdepth 1 \
-newermt 2014-02-28 -not -newermt 2014-04-01 \
-not -name 'build_tools' \
-exec mv {} build_tools \+

Explicação:

  • encontre neste diretório, sem subdiretórios
  • arquivos no intervalo entre 28 de fevereiro e 1º de abril, onde mtse refere ao horário da modificação. Você também pode usar ctpara pesquisar o horário de criação.
  • que não são nomeadosbuild_tools
  • mova todos eles para build_tools. Isso \+significa que todos os nomes de arquivos/diretórios encontrados são substituídos em {}, em vez de um de cada vez. Se você quiser um de cada vez, você precisa \;.

Um par de coisas:

  • Não analise a saída dels. O formato depende do sistema operacional e a escolha de colunas awkfalhará se os nomes dos arquivos/diretórios contiverem espaços em branco.

  • Você costumava &concatenar comandos, mas &apenas colocava um processo em segundo plano. Se fosse, você deveria ter usado &&, mas, no geral, seria bastante complicado conseguir o que deseja.

Responder2

A versão correta para minha solução precisa de xargs para lidar com vários comandos, que podem ser obtidos agrupando os comandos com:

sh -c (or bash -c) 'Command1; Command2; .. Comandn'

Então a solução correta é:

ls -l awk ' $8!=build_tools && $6 ~ /2013-03*/ {print $8}' | xargs -I @ sh -c 'mkdir build_tools/@; mv @ build_tools/@'

Esteja ciente de que isso cria uma nova pasta para cada arquivo a ser movido.

O resultado final é que, embora outros tenham o cuidado de tornar nossa vida mais fácil com ferramentas melhores e especializadas, ainda podemos aprender muito com as consultas canalizadas do estilo antigo. Ao menos em meu caso :)

informação relacionada