bash - 解析 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.'
解决方案
我不确定这是否能回答你的问题,但我认为它至少会让你走上正轨。在结构上,我只是将所有循环组合成一个。这消除了一些可能的逻辑错误,这些错误不会像$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
失败时退出。
推荐阅读
- python - 无法在 Django 中设置默认表单值
- c# - DataGrid 没有输入的最后一行
- firebase - 之前的日内数据会自动合并到主表吗?
- mongodb - 我正在使用 InetAddress 获取服务器 IP,但它解析为本地主机,因为我的服务器名称与服务器 IP 相同,我该怎么办?
- javascript - POSTMAN 产生错误:错误:整数类型的输入语法无效:尝试发送 POST 请求时
- javascript - 在子组件的 ngAfterViewInit() 中调用时,父组件的元素上的 getElementById 返回 null
- twitter - 如何提高 Twitterbot 请求的预渲染速度?
- scala.js - 有没有办法在脚本标签中运行纯 scala 代码
- flutter - 使用 Flutter 打印到 ESC/POS 时如何防止套接字超时错误
- apache-spark - 从列表中删除空字符串(Spark Dataframe)