如何将文件移动到基​​于文本文件的子目录

时间:2018-07-25 13:13:57

标签: linux bash macos shell mv

我的目录中有大约2000个文件。

~/
-File 1.pdf
-File2.pdf
-Another file 1.pdf
-File3.pdf
-Someother file.docx
-Yeanother.pdf 

我已经将每个文件与其关联的帐户进行了映射。此映射在CSV文件中。

文件名目的地

File 1.pdf          | CompanyAccount1
File2.pdf           | CompanyAccount1
Another file 1.pdf  | CompanyAcountA
File3.pdf           | CompanyAccount5
Someother file.docx | AnotherAccount2
Yeanother.pdf       | CompanyAccount1

我想根据基于csv(或文本文件)的帐户名将文件从主目录移动到子目录。

所需结果

~/
-CompanyAccount1
--File 1.pdf
--File2.pdf
--Yeanother.pdf
-CompanyAcountA
--Another file 1.pdf
-CompanyAccount5
--File3.pdf 
-AnotherAccount2
--Someother file.docx

理想情况下,它会像mv < file-and-destination.csv一样简单,但是我无法使其正常工作。我已经尝试过xargs mv < renaming.txt,但是它没有按预期工作(有些已移动,然后其他所有都移动到一个目录中)。

2 个答案:

答案 0 :(得分:0)

检查:

#!/bin/bash
while IFS=" " read -r a b; do
    mkdir -p "$b"
    mv "$a" "${b}/"
done < file.csv

答案 1 :(得分:0)

创建目录:

//The average method using an array

    function average(arr) {
         var sum = arr.reduce(function (a,b) { return a + b; },0)
         return sum/ arr.length
        }
    
//Chunk array method, it returns an array of the sliced arrays by size

    function chunkArray(arr, chunkSize){
        var numChunks = arr.length / chunkSize
        var chunks= []
        for (let index = 0; index < numChunks; index++) {
            chunks.push(arr.slice(index * chunkSize, (index * chunkSize) + chunkSize))   
        }
        return chunks
    }

//Finally, the average of arrays, it returns the average of each array
   
    function averageArrays(arrs){
        return arrs.map(function (arr) {
            return average(arr)
        })
    }

//Example of usage

    var chunks = chunkArray([
        1,2,3,4,5,
        6,7,8,9,0,
        3,4,7,2,1,
        4,6,1,2,3,
        5,6,8,9,3,
        2,3,4,5,6
       ],5)
    console.log(averageArrays(chunks))

这假设文本是制表符分隔的,并且没有文件名包含制表符。

如果所有文件名都不包含空格,则可以简单地cut -f2 file-and-destination.csv | xargs mkdir -p ,但是现在的方式(假设您的示例具有代表性),简单的xargs -n 2 mv <file-and-destination.csv循环似乎是可行的方式。 / p>

while IFS=$'\t' read -r file dir

另一种解决方案是生成脚本以生成目录并移动文件。假设其中也没有文件名带有单引号;

while IFS=$'\t' read -r file dir; do
    mv "$file" "$dir"
done <file-and-destination.csv

这只是生成命令;如果结果看起来合理,则通过管道传递到sed $'s/\\([^\t]*\\)\t\\(.*\\)/mkdir -p \'\\2\'; mv \'\\1\' \'\\2\''

为方便起见,我始终使用Bash“ C样式字符串sh。如果您没有Bash,则第二个特别需要重构。在第一个中,您应该可以简单地删除美元符号并在单引号之间键入文字制表符(在许多shell中, control - v tab 可以在命令行)。

总而言之,我不建议使用后一种技术。如果您可以控制输入文件的格式,只需将$'...'说成destdir/file移到file可能会是一个更好的设计(因为在斜杠上进行拆分很自然,现在您也可以使用带有标签的文件名了。