根据文件名与目录名

时间:2017-02-07 22:11:21

标签: linux bash

我对脚本非常陌生,所以请轻松一点。我知道还有另一个与此相关的论坛,但并不完全涵盖我的问题。

我有一个包含文件的目录和另一个目录,其中包含我需要将每个文件移动到的相应文件夹。每个文件对应于目标目录,如:

DS-123.txt / DS-123_alotofstuffhere /

我想基于文件名的前6个字符与目录的前6个字符的匹配来自动移动。

我有这个:

filesdir=$(ls ~/myfilesarehere/)
dir=$(ls ~/thedirectoriesareinthisfolder/)
for i in $filesdir; do
    for j in $dir; do
        if [[${i:6} == ${j:6}]]; then
                cp $i $j
        fi
    done
done

但是当我运行脚本时,我收到以下错误:

es: line 6: [[_DS-123_morefilenametext.fasta: command not found

我正在使用Linux(不确定超级计算机上的版本,对不起)。

1 个答案:

答案 0 :(得分:1)

最好使用数组和通配符来保存文件和目录列表,而不是ls。通过该更改并对[[ ... ]]部分进行更正,您可以对此进行编码:

files=(~/myfilesarehere/*)
dirs=(~/thedirectoriesareinthisfolder/*)
for i in "${files[@]}"; do
  [[ -f "$i" ]] || continue          # skip if not a regular file
  for j in "${dirs[@]}"; do
    [[ -d "$j" ]] || continue        # skip if not a directory
    ii="${i##*/}" # get the basename of file
    jj="${j##*/}" # get the basename of dir
    if [[ ${ii:0:6} == ${jj:0:6} ]]; then
      cp "$i" "$j"
      # need to break unless a file has more than one destination directory
    fi
  done
done

[[ -d "$j" ]]检查是必要的,因为您的dirs数组也可能包含一些文件。为了更安全,我还添加了$i作为文件的检查。

这是不使用数组的解决方案,如@triplee所建议的那样:

for i in ~/myfilesarehere/*; do
  [[ -f "$i" ]] || continue          # skip if not a regular file
  for j in ~/thedirectoriesareinthisfolder/*; do
    [[ -d "$j" ]] || continue        # skip if not a directory
    ii="${i##*/}" # get the basename of file
    jj="${j##*/}" # get the basename of dir
    if [[ ${ii:0:6} == ${jj:0:6} ]]; then
      cp "$i" "$j"
      # need to break unless a file has more than one destination directory
    fi
  done
done