Renommage des fichiers pour ajouter un suffixe

12

J'ai besoin d'une commande pour renommer tous les fichiers du répertoire de travail actuel, de manière à ce que le nouveau nom de fichier soit identique à l'ancien, mais avec un suffixe correspondant au nombre de lignes des fichiers d'origine (par exemple, si le Le fichier f a 10 lignes, il devrait alors être renommé en f_10 ).

Voici ma tentative (qui ne fonctionne pas):

 linenum=$(wc -l); find * -type f | grep -v sh | rename 's/^/ec/'*
    
posée Martin Yeboah 24.06.2015 - 16:34
la source

7 réponses

13

Que diriez-vous de:

for f in *; do mv "$f" "$f"_$(wc -l < "$f"); done

Par exemple:

$ wc -l *
 10 file1
 40 file2
100 file3
$ ls
file1_10  file2_40  file3_100

Si vous souhaitez conserver les extensions (le cas échéant), utilisez plutôt ceci:

for f in *; do 
    ext=""; 
    [[ $f =~ \. ]] && ext="."${f#*.}; 
    mv "$f" "${f%%.*}"_$(wc -l < "$f")$ext; 
done
    
réponse donnée terdon 24.06.2015 - 17:58
la source
10

Vous pouvez essayer cette doublure:

find . -maxdepth 1 -type f -exec bash -c 'mv -i "$1" "$1.$(wc -l <"$1")"' _ {} \;
  • Ceci trouvera tous les fichiers du répertoire de travail actuel ( find . -maxdepth 1 -type f )

  • Nous exécutons ensuite une instance de shell sur les fichiers trouvés pour renommer les fichiers et leur ajouter le nombre de lignes.

Exemple:

$ ls
bar.txt spam.txt foo.txt

$ find . -maxdepth 1 -type f -exec bash -c 'mv -i "$1" "$1.$(wc -l <"$1")"' _ {} \;

$ ls
bar.txt.12 foo.txt.24 spam.txt.7
    
réponse donnée heemayl 24.06.2015 - 16:46
la source
6

Une autre façon de conserver l'extension (si présente) à l'aide de rename :

for f in *; do rename -n "s/([^.]+)(\.?.*)/\_$(< "$f" wc -l)\/" "$f"; done

Si le résultat est attendu, supprimez l'option -n :

for f in *; do rename "s/([^.]+)(\.?.*)/\_$(< "$f" wc -l)\/" "$f"; done
    
réponse donnée kos 24.06.2015 - 18:14
la source
5

Utilisation de find :

find . -maxdepth 1 -type f -print0 | while read -d $'
% wc -l *
  3 doit
  5 foo

% find . -maxdepth 1 -type f -print0 | while read -d $'
find . -maxdepth 1 -type f -print0 | while read -d $'
% wc -l *
  3 doit
  5 foo

% find . -maxdepth 1 -type f -print0 | while read -d $'%pre%' f; do mv "$f" "$f"_$(grep -c . "$f"); done

% wc -l *                         
  3 doit_3
  5 foo_5
' f; do mv "$f" "$f"_$(grep -c . "$f"); done
' f; do mv "$f" "$f"_$(grep -c . "$f"); done % wc -l * 3 doit_3 5 foo_5
' f; do mv "$f" "$f"_$(grep -c . "$f"); done

Exemple

%pre%     
réponse donnée A.B. 24.06.2015 - 18:14
la source
3

Juste pour le plaisir et rigole une solution avec rename . Puisque rename est un outil Perl qui accepte une chaîne arbitraire évaluée, vous pouvez effectuer toutes sortes de manigances. Une solution qui semble fonctionner est la suivante:

rename 's/.*/open(my $f, "<", $_);my $c=()=<$f>;$_."_".$c/e' *
    
réponse donnée musiKk 25.06.2015 - 13:45
la source
2

Le script ci-dessous couvre plusieurs cas: le point unique et l’extension (fichier.txt), plusieurs points et extensions (fichier.1.txt), des points consécutifs (fichier..foobar.txt) et des points dans le nom du fichier ( fichier. ou fichier ..).

Le script

#!/bin/bash
# Author: Serg Kolo
# Date:  June 25,2015
# Description: script to rename files to file_numlines
# written for http://askubuntu.com/q/640430/295286

# Where are the files ?
WORKINGDIR=/home/xieerqi/substitutions
# Where do you want them to go ?
OUTPUTDIR=/home/xieerqi/substitutions/output

for file in $WORKINGDIR/* ;do 
    FLAG=0
    EXT=$(printf "%s" "$file" | awk -F'.' '{printf "%s",$NF }' )  # extension, last field of dot-separated string
    # EXT="${file##*.}" # Helio's advice is to use parameter expansion, but I dont know how to use it
    if [ -z $EXT ]; then # we have a dot at the end case file. or something
        # so we gotta change extension and filename
        EXT=""
        FILENAME=$(printf "%s" "$file" | awk -F '/' '{ print $NF}' )
        # set flag for deciding how to rename
        FLAG=1
    else
        FILENAME=$( printf "%s" "$file" | awk -F '/' -v var=$EXT '{gsub("."var,"");print $NF}'   ) # filename, without path, lst in
    fi

    NUMLINES=$(wc -l "$file" | awk '{print $1}') # line count

    if [ $FLAG -eq 0 ];then
         echo "$file" renamed as "$OUTPUTDIR"/"$FILENAME"_"$NUMLINES"."$EXT"
        # cp "$file" "$OUTPUTDIR"/"$FILENAME"_"$NUMLINES"."$EXT" # uncomment when necessary
    else
        echo "$file" renamed as "$OUTPUTDIR"/"$FILENAME"_"$NUMLINES""$EXT"
        # cp "$file" "$OUTPUTDIR"/"$FILENAME"_"$NUMLINES""$EXT" # uncomment when necessary
    fi

    #printf "\n"

done

Script en action

$./renamer.sh                                                                                                           
/home/xieerqi/substitutions/file. renamed as /home/xieerqi/substitutions/output/file._0
/home/xieerqi/substitutions/file.. renamed as /home/xieerqi/substitutions/output/file.._0
/home/xieerqi/substitutions/file.1.jpg renamed as /home/xieerqi/substitutions/output/file.1_3.jpg
/home/xieerqi/substitutions/file.1.test.jpg renamed as /home/xieerqi/substitutions/output/file.1.test_3.jpg
/home/xieerqi/substitutions/file.1.test.txt renamed as /home/xieerqi/substitutions/output/file.1.test_2.txt
/home/xieerqi/substitutions/file.1.txt renamed as /home/xieerqi/substitutions/output/file.1_2.txt
/home/xieerqi/substitutions/file.2.jpg renamed as /home/xieerqi/substitutions/output/file.2_3.jpg
/home/xieerqi/substitutions/file.2.test.jpg renamed as /home/xieerqi/substitutions/output/file.2.test_3.jpg
/home/xieerqi/substitutions/file.2.test.txt renamed as /home/xieerqi/substitutions/output/file.2.test_2.txt
/home/xieerqi/substitutions/file.2.txt renamed as /home/xieerqi/substitutions/output/file.2_2.txt
/home/xieerqi/substitutions/foo..bar.txt renamed as /home/xieerqi/substitutions/output/foo..bar_4.txt

Notez qu'il n'y a pas de lignes dans le fichier. et fichier .., le nombre de lignes est donc 0

Merci à terdon et à helio pour avoir examiné le script et les modifications suggérées

    
réponse donnée Sergiy Kolodyazhnyy 24.06.2015 - 23:22
la source
2

Une autre façon de faire, développée avec @Helio en discussion :

for file in *
do
    echo "$file"
    [[ -f "$file" ]] || continue
    [[ $file =~ (.*)(\.[^.]+)$ ]]
    cp "$file" "output/${BASH_REMATCH[1]:-$file}_$(wc -l < "$file")${BASH_REMATCH[2]}"
done

Le gars à l'allure étrange, monoclé avec une deuxième tête rabougrie ( (.*)(\.[^.]+)$ ) ne doit correspondre qu'aux extensions appropriées ( .foo , pas .. ). S'il n'y a pas d'extension, le tableau BASH_REMATCH sera vide. Nous pouvons en tirer parti en utilisant une valeur par défaut pour le nom de fichier ${BASH_REMATCH[1]:-$file} , et en utilisant simplement l'extension telle quelle.

Pour gérer les fichiers de points, vous pouvez utiliser find , comme suggéré par terdon et Helio .

find -maxdepth 1 -type f -printf '%P
for file in *
do
    echo "$file"
    [[ -f "$file" ]] || continue
    [[ $file =~ (.*)(\.[^.]+)$ ]]
    cp "$file" "output/${BASH_REMATCH[1]:-$file}_$(wc -l < "$file")${BASH_REMATCH[2]}"
done
' | while IFS= read -r -d '' file do [[ $file =~ (.*)(\.[^.]+)$ ]] cp "$file" "output/${BASH_REMATCH[1]:-$file}_$(wc -l < "$file")${BASH_REMATCH[2]}" done
    
réponse donnée muru 27.06.2015 - 03:27
la source

Lire d'autres questions sur les étiquettes