itera através de arquivos ('para arquivo em…) e também inclui subdiretórios?

1

Estou usando o sed para fazer várias alterações nos arquivos. Eu acho que a questão é relevante para qualquer operação que deseja iterar através de arquivos que correspondem a um padrão e incluir subdiretórios na recursão de pesquisa de arquivo original E (ou seja, criando-os para replicar a estrutura) na saída de criação de arquivo

Inicialmente obtenho os arquivos com

mkdir -p _seded
for file in *_spec.rb
do
  cat $file
  ... a bunch of seds
  > _seded $file
end

Como posso obter os arquivos e subdiretórios dos arquivos que correspondem ao padrão?

Por exemplo, se eu tiver

spec/ex1
spec/ex2_spec.rb
spec/subs/subex1
spec/subs/subex1_spec.rb
spec/subs/subex2/aaa
spec/subs/subex3/s3_spec.rb
spec/subs/subex4/s4.rb
spec/subs/subex4/bbb

então eu deveria ter:

_seded/ex2_spec.rb
_seded/subs/subex1_spec.rb
_seded/subs/subex3/s3_spec.rb

Observação: os diretórios subex2 e subex4 não devem ser não criados, pois estariam vazios.

Eu tentei:

mkdir -p _seded
find . -name '*_spec.rb' | xargs cat |
  sed -e '[/pattern/replace code]' > _seded/$file

mas tem erros como:

$ ./convert_should_to_expect.sh 
./convert_should_to_expect.sh: line 5: _seded/: Is a directory
xargs: cat: terminated by signal 13
now doing its !!!
sed: couldn't edit _seded/: not a regular file
awk: cmd. line:1: fatal: cannot open file '_seded/' for reading (Is a directory)
mv: '_seded/tmp' and '_seded/tmp' are the same file
sed: couldn't edit _seded/: not a regular file
sed: couldn't edit _seded/: not a regular file
    
por Michael Durrant 02.11.2013 / 16:29

2 respostas

2

você poderia fazer algo assim:

cd spec
find . -type f -name '*_spec.rb' | while read file; do
    mkdir -p ../_seded/"${file%/*}"
    cat "$file" | sed ... > ../_seded/"$file"
done

${file%/*} cortará a parte do nome do arquivo de $file , para que possa ser usada na criação do diretório de saída em mkdir command

    
por 02.11.2013 / 16:41
2

Este é um código não testado! A ideia aqui é dar a lógica que eu acho que você deveria seguir. Isso não inclui subdiretórios, mas pelo menos não criará muitos arquivos vazios como seu código de amostra e terá alguma correção de sintaxe.

O loop for pode ser melhorado com algo como um grep ou uma instrução find para incluir subdiretórios, mas levaria algum tempo para descobrir isso. Talvez alguém saiba do topo de sua cabeça?

mkdir -p _seded
TMPFILE=/var/tmp/sedtmp$$$    # Someone can help me with the syntax for a unique file here. 
for file in *_spec.rb
do
  cat $file
  ... a bunch of seds >> $TMPFILE    # Each with this addition after it.
  COUNT='wc -l $TMPFILE'
  if [ COUNT -gt 0 ]
  then                   
     cp $TMPFILE _seded/$file   
  fi
  > $TMPFILE
done
rm $TMPFILE
    
por 02.11.2013 / 17:07

Tags