2017-06-09 3 views
1

Es gibt mehrere Verzeichnisse, die eine Datei mit dem gleichen Namen enthalten:Kopieren von Dateien aus mehreren Verzeichnissen in einem einzigen Zielverzeichnis

direct_afaap/file.txt 
direct_fgrdw/file.txt 
direct_sardf/file.txt 
... 

Jetzt habe ich sie in ein anderes Verzeichnis extrahieren möchten, direct_new und mit einem anderen Dateinamen wie:

[mylinux~ ]$ ls direct_new/ 
file_1.txt file_2.txt file_3.txt 

Wie kann ich das tun? BTW

, wenn ich will einen Teil des Namens in ursprünglichen Verzeichnis in den Dateinamen setzen, wie:

[mylinux~ ]$ ls direct_new/ 
file_afaap.txt file_fgrdw.txt file_sardf.txt 

Was kann ich tun?

Antwort

1

Dieser kleine Bash-Skript wird es beiden Möglichkeiten:

#!/bin/sh 
# 

# counter 
i=0 

# put your new directory here 
# can't be similar to dir_*, otherwise bash will 
# expand it too 
mkdir newdir 

for file in `ls dir_*/*`; do 
    # gets only the name of the file, without directory 
    fname=`basename $file` 
    # gets just the file name, without extension 
    name=${fname%.*} 
    # gets just the extention 
    ext=${fname#*.} 

    # get the directory name 
    dir=`dirname $file` 
    # get the directory suffix 
    suffix=${dir#*_} 

    # rename the file using counter 
    fname_counter="${name}_$((i=$i+1)).$ext" 

    # rename the file using dir suffic 
    fname_suffix="${name}_$suffix.$ext" 

    # copy files using both methods, you pick yours 
    cp $file "newdir/$fname_counter" 
    cp $file "newdir/$fname_suffix" 
done 

Und die Ausgabe:

$ ls -R 
cp.sh* 
dir_asdf/ 
dir_ljklj/ 
dir_qwvas/ 
newdir/ 
out 

./dir_asdf: 
file.txt 

./dir_ljklj: 
file.txt 

./dir_qwvas: 
file.txt 

./newdir: 
file_1.txt 
file_2.txt 
file_3.txt 
file_asdf.txt 
file_ljklj.txt 
file_qwvas.txt 
+0

downvoter, könnten Sie erklären? Vielleicht kann ich den Code verbessern ... –

+0

Sie müssen 'basename' und' dirname' nicht verwenden, was teuer ist. Außerdem ist das Analysieren von 'ls' keine gute Idee, nur globbing würde gut funktionieren. Außerdem muss kein Suffix extrahiert werden, da es fest ist ('.txt'). Bitte sehen Sie meine [Antwort] (https://stackoverflow.com/a/44479825/6862601). – codeforester

-1

Es kann nicht ganz sein, was Sie wollen, aber es wird die Arbeit machen. Verwenden Sie cp --backup=numbered <source_file> <destination_directory:

$ find . -name test.sh 
./ansible/test/integration/roles/test_command_shell/files/test.sh 
./ansible/test/integration/roles/test_script/files/test.sh 
./Documents/CGI/Code/ec-scripts/work/bin/test.sh 
./Documents/CGI/Code/ec-scripts/trunk/bin/test.sh 
./Test/test.sh 
./bin/test.sh 
./test.sh 

$ mkdir BACKUPS 

$ find . -name test.sh -exec cp --backup=numbered {} BACKUPS \; 
cp: './BACKUPS/test.sh' and 'BACKUPS/test.sh' are the same file 

$ ls -l BACKUPS 
total 28 
-rwxrwxr-x. 1 jack jack 121 Jun 9 10:29 test.sh 
-rwxrwxr-x. 1 jack jack 34 Jun 9 10:29 test.sh.~1~ 
-rwxrwxr-x. 1 jack jack 34 Jun 9 10:29 test.sh.~2~ 
-rwxrwxr-x. 1 jack jack 388 Jun 9 10:29 test.sh.~3~ 
-rwxrwxr-x. 1 jack jack 388 Jun 9 10:29 test.sh.~4~ 
-rwxrwxr-x. 1 jack jack 20 Jun 9 10:29 test.sh.~5~ 
-rwxrwxr-x. 1 jack jack 157 Jun 9 10:29 test.sh.~6~ 

Wenn Sie wirklich in einen Teil des Namens Ordner setzen wollen, müssen Sie genau entscheiden, was Teil, den Sie möchten. Sie könnten natürlich das Verzeichnistrennzeichen durch ein anderes Zeichen ersetzen und den gesamten Pfad in den Dateinamen einfügen.

1
while read -r line; do 
    suffix=$(sed 's/^.*_\(.*\)\/.*$/\1/' <<<$line) 
    newfile=$(sed 's/\.txt/$suffix\.txt/' <<<$line) 
    cp "$line" "~/direct_new/$newfile" 
done <file_list.txt 

Dabei ist file_list eine Liste Ihrer Dateien.

0

Sie können dies mit Bash parameter expansion erreichen:

dest_dir=direct_new 

# dir based naming 
for file in direct_*/file.txt; do 
    [[ -f "$file" ]] || continue # skip if not a regular file 
    dir="${file%/*}"    # get the dir name from path 
    cp "$file" "$dest_dir/file_${dir#*direct_}.txt" 
done 

# count based naming 
counter=0 
for file in direct_*/file.txt; do 
    [[ -f "$file" ]] || continue # skip if not a regular file 
    cp "$file" "$dest_dir/file_$((++counter)).txt" 
done 
  • dir="${file%/*}" entfernt alle Zeichen s von / tarting, Pre-Zuwachs im Grunde, was uns die dirname
  • ${dir#*direct_} entfernt der direct_ Präfix von DIRNAME
  • ((++counter)) verwendet Bash arithmetischen Ausdruck gab auch den Zähler

See:

Verwandte Themen