bash:如何仅将文件名传输/复制到单独的类似文件中?

时间:2016-11-19 23:24:39

标签: linux bash shell

我在文件夹A中的一些文件名称如下:

001_file.xyz
002_file.xyz
003_file.xyz

在另一个文件夹B中我是这样的文件:

001_FILE_somerandomtext.zyx
002_FILE_somerandomtext.zyx
003_FILE_somerandomtext.zyx

现在我想重命名,如果可能的话,只需在bash中的命令行重命名文件夹B中的文件名与文件夹A中的文件名。文件扩展名必须保持不同。 每个文件夹A和B中的文件数量完全相同,并且由于编号,它们都具有相同的顺序。

我是一个总菜鸟,但我希望这个问题的一些简单答案会出现。

提前致谢!

ZVLKX

*为澄清而编辑的示例

2 个答案:

答案 0 :(得分:1)

实现可能看起来像这样:

renameFromDir() {
  useNamesFromDir=$1
  forFilesFromDir=$2

  for f in "$forFilesFromDir"/*; do

    # Put original extension in $f_ext
    f_ext=${f##*.}

    # Put number in $f_num
    f_num=${f##*/}; f_num=${f_num%%_*}

    # look for a file in directory B with same number
    set -- "$useNamesFromDir"/"${f_num}"_*.*
    [[ $1 && -e $1 ]] || {
      echo "Could not find file number $f_num in $dirB" >&2
      continue
    }
    (( $# > 1 )) && {
      # there's more than one file with the same number; write an error
      echo "Found more than one file with number $f_num in $dirB" >&2
      printf '  - %q\n' "$@" >&2
      continue
    }

    # extract the parts of our destination filename we want to keep
    destName=${1##*/}       # remove everything up to the last /
    destName=${destName%.*} # and past the last .

    # write the command we would run to stdout
    printf '%q ' mv "$f" "$forFilesFromDir/$destName.$f_ext"; printf '\n'
    ## or uncomment this to actually run the command
    # mv "$f" "$forFilesFromDir/$destName.$f_ext"
  done
}

现在,我们将如何测试?

mkdir -p A B
touch A/00{1,2,3}_file.xyz B/00{1,2,3}_FILE_somerandomtext.zyx
renameFromDir A B

鉴于此,输出为:

mv B/001_FILE_somerandomtext.zyx B/001_file.zyx
mv B/002_FILE_somerandomtext.zyx B/002_file.zyx
mv B/003_FILE_somerandomtext.zyx B/003_file.zyx

答案 1 :(得分:0)

很抱歉,如果这没有帮助,但我写得很开心。
这会将文件夹B中的项目重命名为文件夹A中的名称,同时保留B的扩展名。

A_DIR="./A"
A_FILE_EXT=".xyz"
B_DIR="./B"
B_FILE_EXT=".zyx"

FILES_IN_A=`find $A_DIR -type f -name *$A_FILE_EXT`
FILES_IN_B=`find $B_DIR -type f -name *$B_FILE_EXT`

for A_FILE in $FILES_IN_A
do
    A_BASE_FILE=`basename $A_FILE`
    A_FILE_NUMBER=(${A_BASE_FILE//_/ })
    A_FILE_WITHOUT_EXTENSION=(${A_BASE_FILE//./ })

    for B_FILE in $FILES_IN_B
    do
        B_BASE_FILE=`basename $B_FILE`
        B_FILE_NUMBER=(${B_BASE_FILE//_/ })

        if [ ${A_FILE_NUMBER[0]} == ${B_FILE_NUMBER[0]} ]; then
            mv $B_FILE $B_DIR/$A_FILE_WITHOUT_EXTENSION$B_FILE_EXT
            break
        fi
    done

done