将多个目录中的文件复制到单个目标目录中

时间:2017-06-09 14:19:54

标签: linux bash shell

有多个目录包含同名文件:

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

现在我想将它们提取到另一个目录direct_new并使用不同的文件名,例如:

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

我该怎么做?

BTW,如果我想将原始目录中的部分名称放入文件名中,例如:

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

我该怎么办?

4 个答案:

答案 0 :(得分: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

其中file_list是您的文件列表。

答案 1 :(得分:1)

这个小BaSH脚本将双向完成:

#!/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

输出:

$ 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

答案 2 :(得分:0)

您可以使用Bash parameter expansion

来实现这一目标
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%/*}"删除从/开始的所有字符,基本上,为我们提供了dirname
  • ${dir#*direct_}从dirname
  • 中删除direct_前缀
  • ((++counter))使用Bash算术表达式预先递增计数器

另见:

答案 3 :(得分:-1)

它可能不是你想要的,但它会完成这项工作。使用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~

如果您真的想要放入部分文件夹名称,则必须准确确定您想要的部分。当然,您可以将目录分隔符替换为其他字符,并将整个路径放入文件名中。