Adicione o sufixo a todos os arquivos sem extensão específica e mantenha a extensão do arquivo

5

Eu tenho um diretório que tem .zip arquivos e outros arquivos (todos os arquivos têm uma extensão) e quero adicionar um sufixo a todos os arquivos sem .zip extensão. Eu sou capaz de pegar um sufixo e colocá-lo em uma variável $suffix , e então eu tentei o seguinte código:

ls -I "*.zip"| xargs -I {} mv {} {}_"$suffix"

Isso lista todos os arquivos sem .zip e está próximo (mas errado). Ele incorretamente produz os seguintes resultados em file.csv :

file.csv_suffix

Eu quero file_suffix.csv - como posso editar meu código para manter a extensão no arquivo?

    
por Foxer 05.10.2017 / 15:27

5 respostas

3

encontrar + abordagens bash :

export suffix="test"

a ) com localizar -exec action:

find your_folder -type f ! -name "*.zip" -exec bash -c 'f=$1; if [[ "$f" =~ .*\.[^.]*$ ]]; then ext=".${f##*\.}"; else ext=""; fi; mv "$f" "${f%.*}_$suffix$ext"' x {} \;

b ) Ou com o bash while loop:

find your_folder/ -type f ! -name "*.zip" -print0 | while read -d $'
export suffix="test"
' f; do if [[ "$f" =~ .*\.[^.]*$ ]]; then ext=".${f##*\.}" else ext="" fi mv "$f" "${f%.*}_$suffix$ext" done
    
por 05.10.2017 / 16:19
4

Usar ls é um pouco perigoso. Veja Por que * not * pars 'ls'?

Você também terá que separar o nome do arquivo, caso contrário, basta anexar $suffix ao final, conforme descobriu.

Aqui segue uma solução usando find e outra sem find .

find . -type f ! -name '*.zip' -exec sh -c 'suffix="$1"; shift; for n; do p=${n%.*}; s=${n##*.}; [ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s"; done' sh "$suffix" {} +

Isso localizará todos os arquivos regulares em algum lugar no diretório atual, cujos nomes não terminam em .zip .

Em seguida, o seguinte script de shell será invocado com uma lista desses arquivos:

suffix="$1"  # the suffix is passed as the first command line argument
shift        # shift it off $@
for n; do    # loop over the remaining names in $@
    p=${n%.*}    # get the prefix of the file path up to the last dot
    s=${n##*.}   # get the extension of the file after the last dot

    # rename the file if there's not already a file with that same name
    [ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s"
done

Teste:

$ touch file{1,2,3}.txt file{a,b,c}.zip
$ ls
file1.txt file2.txt file3.txt filea.zip fileb.zip filec.zip

$ suffix="notZip"
$ find . -type f ! -name '*.zip' -exec sh -c 'suffix="$1"; shift; for n; do p=${n%.*}; s=${n##*.}; [ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s"; done' sh "$suffix" {} +

$ ls
file1_notZip.txt    file3_notZip.txt    fileb.zip
file2_notZip.txt    filea.zip           filec.zip

O script de shell acima pode ser executado independentemente de find se o número de arquivos não for muito grande e se você não precisar recorrer a subdiretórios (apenas levemente modificados para pular nomes que não são arquivos):

#!/bin/sh

suffix="$1"  # the suffix is passed as the first command line argument
shift        # shift it off $@
for n; do    # loop over the remaining names in $@

    [ ! -f "$n" ] && continue  # skip names of things that are not regular files

    p=${n%.*}    # get the prefix of the file path up to the last dot
    s=${n##*.}   # get the extension of the file after the last dot

    # rename the file if there's not already a file with that same name
    [ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s"
done

Com bash , você executaria isso nos arquivos em um diretório como este:

$ shopt -s extglob
$ ./script.sh "notZip" !(*.zip)

Com a opção extglob shell definida em bash , !(*.zip) corresponderia a todos os nomes no diretório atual que não terminam com .zip .

    
por 05.10.2017 / 15:59
3

No bash:

shopt -s extglob
suffix=yoursuffix
for entry in !(*.zip)
do
  [[ -f "$entry" ]] || continue
  base=${entry%.*}
  if [[ "$entry" =~ \. ]]
  then
    ext=${entry##*.}
    echo mv -- "$entry" "${base}_${suffix}.${ext}"
  else
    echo mv -- "$entry" "${base}_${suffix}"
  fi
done

Remova o echo quando parecer correto para você.

Casos de teste:

touch a.zip b.zip foo bar file.csv a.file.csv 'test case' 'test case.csv'
mkdir baz

Exemplo de saída:

mv -- a.file.csv a.file_yoursuffix.csv
mv -- bar bar_yoursuffix
mv -- file.csv file_yoursuffix.csv
mv -- foo foo_yoursuffix
mv -- scr scr_yoursuffix
mv -- test case test case_yoursuffix
mv -- test case.csv test case_yoursuffix.csv

... ignorando o diretório baz , mas renomeando foo e bar apropriadamente.

    
por 05.10.2017 / 16:00
1
 find <pathtodirectory> ! -name *.zip | awk -v suff=$suffix -F\. '{ print $1"_"suff"."$2 }'

Você pode usar find para listar os arquivos e, em seguida, analisar a saída pelo awk. Quando estiver satisfeito com a lista de arquivos com o novo sufixo incluído, você poderá executar o comando novamente pelo awk, utilizando a função do sistema do awk para criar, comandar e executar o mesmo

find <pathtodirectory> ! -name *.zip | awk -v suff=$suffix -F\. '{ system("mv "$0" "$1"_"suff"."$2) }'

Observe que existem riscos de injeção de comando com a solução. Note também que a solução depende de todos os arquivos que possuem a estrutura filename.extension, que pode ou não ser o caso.

    
por 05.10.2017 / 15:50
-1
for f in 'ls -I "*.zip" '; do mv $f 'echo $f | cut -d '.' -f1'_suffix.'echo $f | cut -d '.' -f2' ; done ;

Outras ferramentas interessantes incluem utilitários como renomear

Esta é uma pergunta interessante, mas isso também significa que provavelmente já foi perguntado muitas vezes . Note que mantive o comando l's, que não exclui diretórios.

    
por 05.10.2017 / 15:54