Script para preceder o caminho dos arquivos para um arquivo recursivamente

2

Eu trabalho como aluno e os arquivos enviados para mim acabam em uma pasta com o nome do aluno, que está dentro de uma pasta específica no meu compartilhamento linux.

Atualmente, passo por cada arquivo de origem e adiciono manualmente um comentário na parte superior de cada arquivo para que, quando eu os imprimir, possa saber quais arquivos pertencem a quais alunos.

O que eu quero fazer é recursivamente percorrer a pasta de trabalhos de casa e, quando eu passo para a pasta de cada aluno, adicionar um comentário ao topo de cada arquivo naquela pasta usando o nome do diretório do aluno para saber o que colocar no comentário.

Isso parece semelhante no que diz respeito a adicionar comentários na parte superior do arquivo, mas não sei como criar dinamicamente o comentário enquanto eu coloco a pasta de cada aluno.

Atualização mais recente

Ainda não funciona ainda, mas aqui estão as mudanças que fiz para que você não tenha que procurá-las.

Eu fiz algumas alterações:

  • As aspas simples na instrução printf agora são aspas duplas, pois o ' in isn't estava terminando cedo.
  • O% de-writable alterado para -perm 664 writable apresentou um erro e todos os arquivos que estou tentando alterar são definidos como 644 quando são enviados. Se você conhece uma maneira melhor do que isso, me avise.
  • Se eu entendi exec corretamente agora $ 1 não é declarado (adicionando echo $1 no argumento exec confirmou isso) então eu adicionei _filepath={} e removi o {} no final do argumento exec.
  • Inicialize _dirname com _filepath
  • Nas duas linhas que usam regex para isolar o nome do diretório, as aspas duplas não foram fechadas. Agora o _dirname retém com sucesso apenas o nome do diretório
  • Agora é invocado com _filepath

Tenho certeza de que a razão pela qual isso não funciona é que aspas simples na linha invocadas estão fechando o argumento exec.

código atual:

student_head_action() {
   # We can't use parameter expansion on $PWD because of recursion
   local _dirname="${1%/*}"
   _dirname="${_dirname##*/}"

   [[ -d $1 ]] && return 0
   if ! [[ -w $1 && -f $1 ]]; then
      printf '%s\n' "$1 does not exist or is not writeable, skipping"
      return 1
   fi
   ed -s "$1" <<< $'0a\n'"//${_dirname}"$'\n.\n,s/\r//g\nw'
}

student_head() {
   local _file
   if (( $# )); then
      for _file; do
         student_head_action "${_file}" || _retval=1
      done
   else
      if shopt -qs globstar; then
         for _file in **/*; do
            student_head_action "${_file}" || _retval=1
         done
         shopt -u globstar
      else
         printf "%s\n" "Globstar isn't available, attempting to use GNU find ..."
         find . -type f -perm 644 -exec bash -c '
            _filepath={}
            _dirname=$_filepath
            _dirname="${_dirname%/*}"
            _dirname="${_dirname##*/}"
            echo $_dirname
            ed -s "$_filepath" <<< '"$'0a\n'"'"//${_dirname}"'"$'\n.\n,s/\r//g\nw'" \;
      fi
   fi
   return "${_retvalue-0}"
    
por Matt 16.09.2011 / 18:08

2 respostas

5

Você pode executar student_head quando estiver em uma pasta para adicionar automaticamente o nome da pasta como um cabeçalho a arquivos graváveis nela e em seus subdiretórios:

student_head_action() {
    # We can't use parameter expansion on $PWD because of recursion
    local _dirname="${1%/*}"
    _dirname="${_dirname##*/}"

    [[ -d $1 ]] && return 0
    if ! [[ -w $1 && -f $1 ]]; then
        printf '%s\n' "$1 does not exist or is not writeable, skipping"
        return 1
    fi
    bash -c "ed -s {} <<< $'0a\n'"# Student: ${_dirname}"$'\n.\n,s/\r//g\nw'"
}

student_head() {

    local _file
    if (( $# )); then
        for _file; do
            student_head_action "${_file}" || _retval=1
        done
    else
        if shopt -s globstar > /dev/null 2>&1; then
            for _file in **/*; do
                student_head_action "${_file}" || _retval=1
            done
           shopt -u globstar
        else
            printf '%s\n' 'Globstar isn't available, attempting to use GNU find...'
            find . -type f -writable -exec bash -c '
                _dirname="${1%/*}\
                _dirname="${_dirname##*/}\
                ed -s "$1" <<< '"$'0a\n'"'"# Student: ${_dirname}"'"$'\n.\n,s/\r//g\nw'" {} \;
        fi                
    fi

    return "${_retval-0}"
}

Coloque essas funções em ~/.bashrc se quiser que student_head seja sempre acessível ao usuário ao usar bash .

student_head pode ser chamado de duas maneiras:

  1. Sem argumentos. Nesse modo, todos os arquivos graváveis no diretório atual e em seus subdiretórios têm o cabeçalho incluído.
  2. Com nomes de arquivos como argumentos. Neste modo, apenas os arquivos listados nos argumentos têm o cabeçalho adicionado.

Se um arquivo nos argumentos não existir, student_head retornará um status de saída de 1.

Deve-se mencionar que este script usa globstar , que requer bash>=4.0 .

    
por 16.09.2011 / 18:27
2

Aqui está uma solução que combina find e ed .

add_header() {
   declare regex IFS='|'
   (( $# )) && regex="^($*)$" || regex=""
   find "$PWD" -type f -exec bash -c ' 
      ( exec grep -E -qs -e "$0" <<<"${1##*/}" ) || exit
      _dirname="${1%/*}"
      _dirname="${_dirname##*/}"
      exec ed -s "${1}" <<EOF
0a
# Student: ${_dirname}
.
wq
EOF
   ' "${regex:-.+}" '{}' \;
   return 0
}

add_header                    # all files in current directory recursively
add_header file1 file2 file3  # only named files in current directory recursively
    
por 16.09.2011 / 20:13