Como obter nomes de arquivos em um diretório e escrevê-los em um arquivo usando o shell script?

1

Eu preciso obter os nomes dos arquivos que estão iniciando com um testfile de string. Também quero criar um arquivo XML no mesmo local e gravar esses nomes de arquivo no XML.

<path>
 <dir>
     <file>testfile1</file>
 </dir>
 <dir>
     <file>testfile2</file>
 </dir>
<path>
    
por newbie dev 25.12.2011 / 14:18

2 respostas

2

Como disse @slhck, o shell não é realmente a ferramenta certa para escrever XML (embora não seja tão ruim quanto tentar analisar o XML no shell ...), mas não é muito difícil fazer um download rápido e sujo script:

targetdir="/path/to/dir/of/files"
prefix="testfile"
outfile="$targetdir/out.xml"

# Write the opening tag(s):
echo "<path>" >"$outfile"

# Loop through the matching files, writing entries for each one:
for f in "$targetdir/$prefix"*; do
    cat <<END_INSERT >>"$outfile"
 <dir>
  <file>$(basename "$f")</file>
 </dir>
END_INSERT
done

# Write the closing tag(s):
echo "</path>" >>"$outfile"

Então, o que há de errado com o acima, que você gostaria de usar algo com uma biblioteca XML real em vez disso? Bem, considere o que aconteceria com o item acima se algum nome de arquivo contiver "<" ou ">" (que são perfeitamente caracteres legais em nomes de arquivos unix)? Fazer isso corretamente envolve codificar os nomes dos arquivos com entidades HTML e (AFAIK) o shell não possui boas ferramentas para isso; uma boa biblioteca XML irá lidar com esse tipo de coisa automaticamente.

Algumas notas no script: primeiro, observe que o primeiro echo redireciona com ">", enquanto todas as gravações subseqüentes no arquivo de saída usam "> >" - isso é porque ">" esvazia o arquivo antes de escrever, então você quer isso apenas na primeira gravação.

Em segundo lugar, eu uso echo para a primeira e a última gravações, mas cat com um documento aqui no loop - isso é apenas uma questão de conveniência, porque echo é mais fácil para gravações de linha única , mas o here-docs é mais fácil de fazer gravações em várias linhas. Você poderia facilmente usar echo em todos os lugares ou cat << em todos os lugares se quisesse ser consistente.

Em terceiro lugar, tenho a tendência de citar duas vezes tudo o que contém uma variável. Esta é uma maneira de evitar problemas com caracteres especiais (como espaços) em coisas como nomes de arquivos. Em geral, eu sigo o princípio de que você deve citar tudo, a menos que haja uma razão específica para não citar. É ruim o suficiente o XML terá problemas com caracteres especiais, eu não quero problemas no nível do shell também.

    
por 25.12.2011 / 20:47
1

É possível para o bash shell criar um arquivo XML contendo os nomes dos arquivos correspondentes a um padrão (neste caso, testfile* ):

#!/bin/bash

XML_LIST="$HOME/xml.list"
touch $XML_LIST
#find files matching the regex
find /home/ -name "testfile*" -print0 | xargs -n1 -0  >> /tmp/temp_filelist

echo "<path>" > $XML_LIST

#read list of files from TMP_FILE
#declare array 
declare -a FILE_NAMES
#open file for reading to array
exec 10</tmp/temp_filelist
while read LINE <&10; do
    FILE_NAMES[$count]=$LINE
    if [ "$LINE" != "" ]; then
        echo " <dir>" >> $XML_LIST
        echo "     <file>$LINE</file>" >> $XML_LIST
        echo " </dir>" >> $XML_LIST
    fi
done
#close temp read file 
exec 10>&-

echo "</path>" >> $XML_LIST
echo "done"

Ler isso no shell será mais complicado, mas ainda assim totalmente possível.

Para esse tipo de script, eu recomendaria outra linguagem nativa do Linux, a Python, que é fácil de aprender e possui uma biblioteca XML especializada para possibilitar o processo de gravação acima, além de ler o arquivo XML em menos linhas de código. !

    
por 25.12.2011 / 21:30

Tags