Batch renomeando arquivos txt para combinar com a pasta, tudo no mesmo diretório?

0

Em ~ / Desktop / a /, eu tenho pastas (com nomes que possuem espaços) e arquivos txt no formulário:

100 description of project A
100_notes.txt
200 description of project B
200_notes.txt

O que eu gostaria:

100 description of project A
100 description of project A.txt
200 description of project B
200 description of project B.txt

Este é o script até agora:

#!/bin/bash
cd ~/Desktop/a/
for i in *; do
  mv "$i/${f%.txt}" "$i.txt";
done

Estou tentando com arquivos de teste e renomeia a pasta para ter uma extensão .txt, que não é o que eu quero.

    
por user10630009 11.11.2018 / 08:08

1 resposta

1
#!/bin/sh

for notes in ./???_notes.txt
do
    if [ ! -f "$notes" ]; then
        continue
    fi

    num=${notes%_notes.txt}

    set -- "$num "*/
    if [ "$#" -gt 1 ]; then
        echo 'More than one directory found:' >&2
        printf '\t%s\n' "$@" >&2
        printf 'Skipping %s...\n' "$notes" >&2
        continue
    elif [ ! -d "$1" ]; then
        printf 'No directory matching "%s" found\n' "$num */" >&2
        printf 'Skipping %s...\n' "$notes" >&2
        continue
    fi

    printf 'Would rename "%s" into "%s"\n' "$notes" "${1%/}.txt"
    # mv -i "$notes" "${1%/}.txt"
done

Este script iria iterar todos os arquivos NNN_notes.txt no diretório atual. Para cada arquivo, o número NNN (que pode ser qualquer string de três letras) é extraído e usado para detectar qualquer diretório chamado NNN seguido por um espaço e uma string arbitrária.

Se um único diretório for encontrado, o arquivo será renomeado de acordo (a renomeação real é comentada por segurança). Se mais de um diretório ou nenhum diretório for encontrado, uma mensagem indicando isso é exibida.

A substituição do parâmetro ${variable%string} remove a string string do final do valor de $variable . O comando set , quando usado como neste script, define os parâmetros posicionais, $1 , $2 , $3 etc. para as coisas que correspondem ao padrão de globbing de nome de arquivo fornecido (neste script, queremos que o padrão seja corresponde exatamente a um diretório). O valor $# é o número de tais parâmetros posicionais.

A maneira como escrevi esse script, seria executável por bash e /bin/sh . Não usa nenhum "bashisms".

Uma versão bash -only:

#!/bin/bash

shopt -s nullglob

for notes in ./???_notes.txt
do
    num=${notes%_notes.txt}

    dirs=( "$num "*/ )
    if [ "${#dirs[@]}" -gt 1 ]; then
        echo 'More than one directory found:' >&2
        printf '\t%s\n' "${dirs[@]}" >&2
        printf 'Skipping %s...\n' "$notes" >&2
        continue
    elif [ "${#dirs[@]}" -eq 0 ]; then
        printf 'No directory matching "%s" found\n' "$num */" >&2
        printf 'Skipping %s...\n' "$notes" >&2
        continue
    fi

    printf 'Would rename "%s" into "%s"\n' "$notes" "${dirs[0]%/}.txt"
    # mv -i "$notes" "${dirs[0]%/}.txt"
done

A maior diferença aqui é que usamos uma matriz nomeada dirs para manter as possíveis expansões do padrão "$num "*/ e que usamos a opção nullglob shell para fazer com que os padrões de nome de arquivo não correspondentes sejam expandidos para nada. / p>     

por 11.11.2018 / 12:06

Tags