2014-06-08 3 views
8

Ich bin neu in Awk und Shell-basierte Programmierung. Ich habe eine Reihe von Dateien Name file_0001.dat, file_0002.dat......file_1000.dat. Ich möchte die Dateinamen ändern, wie die Zahl, nachdem Datei_ ein Vielfaches von 4 im Vergleich zum vorherigen Dateinamen ist. SO möchte ich ändernEin Skript zum Ändern von Dateinamen

file_0001.dat to file_0004.dat 
file_0002.dat to file_0008.dat 

und so weiter.

Kann jemand ein einfaches Skript vorschlagen, um es zu tun. Ich habe folgendes versucht, aber ohne Erfolg.

#!/bin/bash 
a=$(echo $1 sed -e 's:file_::g' -e 's:.dat::g') 
b=$(echo "${a}*4" | bc) 
shuf file_${a}.dat > file_${b}.dat 
+0

ich Hilfe CNA Sie mit einem Java oder PHP-Skript für diese. Sie müssen zuerst den Ordner durchsuchen und alle Dateinamen behalten, dann den neuen Namen zuordnen und dann von der höchsten zur niedrigsten beginnen. Als ob du vom Niedrigsten gehst - es wird Konflikte geben. Beispiel kann nicht 001 zu 004 umbenennen, wenn es ein 004 von vorher gibt. – tgkprog

+0

@tgkprog - Sieht so aus, als ob er awk/sed/bash benutzen möchte (welche die besseren Werkzeuge für diese Aufgabe sind). – jahroy

+0

Sie sollten eine richtige Antwort wählen, warum? Siehe [faq] – tgkprog

Antwort

2

Dieses Skript wird für Sie den Trick tun:

#!/bin/bash 
for i in `ls -r *.dat`; do 
    a=`echo $i | sed 's/file_//g' | sed 's/\.dat//g'` 
    almost_b=`bc -l <<< "$a*4"` 
    b=`printf "%04d" $almost_b` 
    rename "s/$a/$b/g" $i 
done 

Dateien vor:

file_0001.dat file_0002.dat

Dateien nach der ersten Ausführung:

file_0004.dat file_0008.dat

Dateien nach der zweiten Ausführung:

file_0016.dat file_0032.dat

+1

Beginnen Sie von der höchsten und gehen Sie zum niedrigsten. Als ob du vom Niedrigsten gehst - es wird Konflikte geben. Beispiel kann man 001 nicht in 004 umbenennen, wenn es ein 004 von vorher gibt ... was ist, wenn es zuerst datei_0001.dat, datei_0001.dat, ... datei_0004.dat ... hat? – tgkprog

+1

Danke tgkprog - Ich habe den Code geändert, um das zu verhindern. Vielen Dank. –

-1

Dies kann helfen:

#!/bin/bash 
for i in `cat /path/to/requestedfiles |grep -o '[0-9]*'`; do 
    count=`bc -l <<< "$i*4"` 
    echo $count 
done 
1

Hier eine reine Bash-Art, es zu tun (ohne bc, umbenennen oder sed).

#!/bin/bash 

for i in $(ls -r *.dat); do 
    prefix="${i%%_*}_" 
    oldnum="${i//[^0-9]/}" 
    newnum="$(printf "%04d" $((10#$oldnum * 4)))" 
    mv "$i" "${prefix}${newnum}.dat" 
done 

es testen Sie

mkdir tmp && cd $_ 
touch file_{0001..1000}.dat 
(paste code into convert.sh) 
chmod +x convert.sh 
./convert.sh 
1

Mit bash/sed/Fund tun können:

files=$(find -name 'file_*.dat' | sort -r) 
for file in $files; do 
    n=$(sed 's/[^_]*_0*\([^.]*\).*/\1/' <<< "$file") 
    let n*=4 
    nfile=$(printf "file_%04d.dat" "$n") 
    mv "$file" "$nfile" 
done 
1

ls -r1 | awk -F '[_.]' '{printf "%s %s_%04d.%s\n", $0, $1, 4*$2, $3}' | xargs -n2 mv

  1. ls -r1 Listendatei in umgekehrter Reihenfolge, Konflikte zu vermeiden
  2. Der zweite Teil erzeugt einen neuen Dateinamen. Zum Beispiel: file_0002.dat wird file_0002.dat file_0008.dat werden
  3. xargs -n2 zwei Argumente jedes Mal mv
1

passieren Dies könnte für Sie arbeiten:

paste <(seq -f'mv file_%04g.dat' 1000) <(seq -f'file_%04g.dat' 4 4 4000) | 
sort -r | 
sh