首页 > 解决方案 > 解析 CSV 以找到与代码对应的名称,然后将具有匹配代码的文件夹复制到具有相应名称的文件夹

问题描述

我正在尝试使用 bash 脚本自动打包来自各种来源的文件和内容。

我有一个主目录,其中包含pdf文件、csv 文件和带有附加内容的各种文件夹。文件夹以它们所属的位置代码命名,例如190,191等。

我的 csv 文件中的典型行如下所示:form_letters_Part1.pdf,PX_A31_smith.adam.pdf,190,

第一列是原名pdf,第二​​列是要重命名的名称,第三列是该人所属的位置代码。

我的脚本的第一部分将pdf文件从求职信格式重命名为该PX_A31...格式,然后为每个文件创建一个目录并将它们移动到其中。

#!/usr/bin/tcsh bash
sed 's/"//g' rename_list_lab.csv | while IFS=, read orig new num; do 
    mv "$orig" "$new"
done
echo 'Rename  Done.'
for file in *.pdf; do
    mkdir "${file%.*}"
    mv "$file" "${file%.*}"
done
echo 'Directory creation done.'

接下来需要发生的是将具有特定位置内容的文件夹复制到刚刚创建的那些新目录中,对应于 csv 文件中的位置代码。

所以我在上面的echo 'Directory Creation Done.'行之后尝试了这个:

echo 'Directory Creation Done.'
sed 's/"//g' rename_list.csv | while IFS=, read orig new num; do 
    for folder in *; do
        if [[ -d .* = "$num" ]]; then
            cp -R "$folder" "${file%.*}"
        fi
done
echo 'Code Folder Contents Sort Done.'

但是,这会导致语法错误:

syntax error in conditional expression
syntax error near `='
`                    if [[ -d .* = "$num" ]]; then'

编辑:为了澄清第二部分if语句,语句的预期逻辑如下:对于当前目录中的项目,如果它是一个目录,并且目录的名称与 csv 中的位置代码匹配,那么该目录应该被复制到 csv 中具有相同对应位置代码的任何目录。

换句话说,如果从第一部分新创建的目录PX_A31_smith.adam在上面的 csv 行中的位置代码是 190,那么190应该将调用的文件夹复制到目录PX_A31_smith.adam中。

如果其他三个人在 csv 中也有 190 代码,则该190目录也应复制到这些人。

编辑 2:我解决了语法错误,还意识到我有一个未终止的do语句。修复这些,似乎仍然无法评估if声明。更新脚本如下:

#!/usr/bin/tcsh bash
sed 's/"//g' rename_list.csv | while IFS=, read orig new num; do 
    mv "$orig" "$new"
done
echo '1 Done.'
for file in *.pdf; do
    mkdir "${file%.*}"
    mv "$file" "${file%.*}"
done
echo '2 done.'
sed 's/"//g' rename_list.csv | while IFS=, read orig new num; do 
    for folder in * ; do
        if [[ .* = "$num" ]]; then
            cp -R "$folder" "${file%.*}"
            else echo "No matches found."
        fi
    done
done
echo '3 Done.'

标签: bashshellunixscripting

解决方案


我不确定这是否能回答你的问题,但我认为它至少会让你走上正轨。在结构上,我只是将所有循环组合成一个。这消除了一些可能的逻辑错误,这些错误不会像$file第二部分中使用的那样被视为语法错误。这是第一部分循环的局部变量,不再存在。但是,这将被解释为一个空字符串。

#!/usr/bin/bash
#^Fixed shebang line.

sed 's/"//g' rename_list.csv | while IFS=, read -r orig new num; do 

    if [[ -f $orig ]]; then          #If the file we want to rename is indeed a file.
        mkdir "${new%.*}"            #make the directory from the file name you want
        mv "$orig" "${new%.*}/$new"  #Rename when we move the file into the new directory

        if [[ -d $num ]]; then       #If the number directory exists
            cp -R "$num" "${new%.*}" #Fixed this based on your edit.
        else
            #Here you can handle what to do if the number directory does not exist.
            echo "$num is not a directory."
        fi

    else  
        #Here you can handle what to do if the file does not exist.
        echo "The file $orig does not exist."
    fi

done

根据您的说明进行编辑

注意:就错误检查而言,这是相当缺乏的。请记住,这些功能中的任何一个都可能失败,这将产生不良行为。检查if [[ $? != 0 ]]以检查最后发出的命令的退出状态(0 表示成功)。你也可以做一些事情,比如mkdir somedir || exit 2失败时退出。


推荐阅读