如何重命名添加前缀的目录中的所有文件

时间:2014-11-15 05:52:22

标签: linux loops rename

我首先创建10位数的随机数

export mask=$RANDOM$RANDOM$RANDOM; let "mask %= 10000000000";

此命令效果很好

for i in /home/testing/*; do mv "$i" "$mask$i"; done

上述命令的问题在于它只适用于我在/ home / testing中。一旦我移动脚本,我就会收到此错误

mv: cannot move ‘/home/testing/rec001.mp4’ to ‘3960731225/home/testing/rec001.mp4’: No such file or directory

我在这里做错了什么?

3 个答案:

答案 0 :(得分:1)

在应用path之前,您需要将filenamemask 分开。例如,要在脚本中使用目录作为参数传递给脚本:

path="$1"

## Note: this assumes you are exporting mask earlier. If not, set mask here

for i in "${path}"/*; do

    dir="${i%/*}"       # path component
    ffname="${i##*/}"   # filename component

    mv "$i" "${dir}/${mask}${ffname}"

done

这将mask应用于给定目录中的所有文件,无论目录在何处。

包含此内容的脚本示例如下所示。您可以将此脚本保存在任何您喜欢的位置。您可以将其设为可执行文件chmod 0755 scriptname,也可以使用bash scriptname进行调用。要使用该脚本,请在第一个参数中添加要作为文件前缀的路径。 E.g bash scriptname /path/to/files(如果您使其可执行,则只需scriptname /path/to/files):

#!/bin/bash

# validate input
[ -n "$1" ] || {
    printf "error: insufficient input. Usage: %s /path/to/files\n" "${0//\//}"
    exit 1
}

# validate directory
[ -d "$1" ] || {
    printf "error: directory not found: '%s'\n" "$1"
    exit 1
}

path="$1"

## Note: this assumes you are exporting mask earlier. If not, set mask here

## validate mask set and is 10 chars (added per comment)
[ -n "$mask" -a "${#mask}" -eq 10 ] || {
    printf "error: mask '%s' either unset or not 10 characters\n" "$mask"
    exit 1
}

# move files
for i in "${path}"/*; do

    [ -f "$i" ] || continue  # if not file, skip

    dir="${i%/*}"            # path component
    ffname="${i##*/}"        # full filename component (with .ext)

    mv "$i" "${dir}/${mask}${ffname}"

done

以下是在当前工作目录中的prefix.sh目录上调用时以及在当前目录外dat上调用时,使用名为~/tmp的脚本将发生什么移动的示例:

输出(掩码= 3960731225):

$ ./prefix.sh dat

 dat/f1f2.dat   => dat/3960731225f1f2.dat
 dat/field.txt  => dat/3960731225field.txt
 dat/flop.txt   => dat/3960731225flop.txt
 dat/hh.dat     => dat/3960731225hh.dat
 dat/hh1.dat    => dat/3960731225hh1.dat
 dat/hostnm     => dat/3960731225hostnm
 dat/hosts.dat  => dat/3960731225hosts.dat

$ ./prefix.sh ~/tmp

  /home/david/tmp/tcpd.tar.xz      => /home/david/tmp/3960731225tcpd.tar.xz
  /home/david/tmp/tcpdump-capt     => /home/david/tmp/3960731225tcpdump-capt
  /home/david/tmp/tcpdump.new.1000 => /home/david/tmp/3960731225tcpdump.new.1000
  /home/david/tmp/test             => /home/david/tmp/3960731225test

答案 1 :(得分:1)

有两个非常有用的命令,basename和dirname。 他们会给你dir部分和文件名,看看这个测试脚本。

#!/bin/bash

mask=$RANDOM$RANDOM$RANDOM; let "mask %= 10000000000";
echo $mask

mkdir -p testing
> testing/nisse.txt
> testing/guste.txt
> testing/berra.txt

ls testing/

for i in testing/*
do 
    file=$(basename $i)
    dir=$(dirname $i)
    newfile=$mask$file
    echo $i $dir $file $newfile

    mv "$dir/$file" "$dir/$newfile"
done

ls testing/

它会输出:

247639260
berra.txt  gusten.txt  nisse.txt
testing/berra.txt testing berra.txt 247639260berra.txt
testing/guste.txt testing guste.txt 247639260guste.txt
testing/nisse.txt testing nisse.txt 247639260nisse.txt
247639260berra.txt  247639260guste.txt  247639260nisse.txt

请注意,我写得非常详细,以使其更清晰,更易读。

答案 2 :(得分:0)

如果要在现有命令之前添加cd命令,无论您想要移动它运行的脚本,

cd /home/testing

for i in /home/testing/*; do mv "$i" "$mask$i"; done