Bash:遍历文本文件中列出的文件并移动它们

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6566591/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 00:17:48  来源:igfitidea点击:

Bash: Loop over files listed in a text file and move them

macosbashfilefor-loopmove

提问by PatentDeathSquad

I have a directory (directory A) with 10,000 files in it. I want to move some of them to directory B and the others to directory C. I made a text file that contains the names of all the files I want to move to directory B and another one with the names of all the files that I want to move to directory C. How can I write a bash for loop to move these files to the new directories.

我有一个包含 10,000 个文件的目录(目录 A)。我想将其中一些移动到目录 B,其他移动到目录 C。我制作了一个文本文件,其中包含要移动到目录 B 的所有文件的名称,另一个包含我想要的所有文件的名称移动到目录 C。我如何编写一个 bash for 循环来将这些文件移动到新目录。

Pseudocode:

伪代码:

for file in textfileB:
move file from directory A to directory B

对于 textfileB 中的文件:
将文件从目录 A 移动到目录 B

for file in textfileC:
move file from directory A to directory C

对于 textfileC 中的文件:
将文件从目录 A 移动到目录 C

Sorry if this is asked somewhere else, but I've spent hours trying to learn bash and I just don't get it. I wasn't able to find something similar enough in another thread that I could understand (maybe I just don't know the right search words).

抱歉,如果在其他地方有人问过这个问题,但我花了几个小时试图学习 bash,但我就是不明白。我无法在另一个我能理解的线程中找到足够相似的内容(也许我只是不知道正确的搜索词)。

I got something like this, but I couldn't get it working:

我得到了这样的东西,但我无法让它工作:

FILES=[dont' know what goes here? An array? A list?  

Can I just state the text file name and if so what format do the files have to be? name1.ext, name2.ext, or name1.ext name2.ext]

我可以只说明文本文件名吗?如果可以,文件必须是什么格式?name1.ext、name2.ext 或 name1.ext name2.ext]

for f in $FILES; do mv $f /B/$f [not sure about the second argument for mv]; done

thx

谢谢

BTW Mac OSX 10.6.8 (Snow Leopard) Apple Terminal v. 2.1.2 / 273.1 Bash 3.2

BTW Mac OSX 10.6.8 (Snow Leopard) Apple Terminal v. 2.1.2 / 273.1 Bash 3.2

回答by asveikau

cat file-list.txt | while read i; do
   # TODO: your "mv" command here.  "$i" will be a line from
   # the text file.
done

回答by Ignacio Vazquez-Abrams

BASH FAQ entry #1: "How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?"

BASH 常见问题条目 #1:“如何逐行(和/或逐字段)读取文件(数据流、变量)?”

If the filename will remain the same then the second argument to mvcan be just the directory.

如果文件名保持不变,则第二个参数mv可以只是目录。

回答by Vijay

directory of the script should be the your location of the files

脚本的目录应该是您的文件位置

TO_B=file1.txt
TO_C=file2.txt

for file in $TO_B
do
mv ${file} B/
done

for file in $TO_C
do
mv ${file} C/
done

回答by Laxman Singh

you can move 1000 or 1000 user directory without take much time where thousand of user directory exist.

您可以移动 1000 或 1000 个用户目录,而无需花费太多时间在存在数千个用户目录的情况下。

cat deleteduser | while read i;  do mv -vv $i ../deleted_user; done; 
deleteuser= user name list
../deleted_user= destination dir

回答by anon

Using bash, having a huge filelist containing strings with leading and/or closing spaces I'd propose:

使用 bash,有一个巨大的文件列表,其中包含带有前导和/或关闭空格的字符串,我建议:

less 'file-list.txt' | while read -r; do mv "$REPLY" /Volumes/hard_drive_name/new_destination_directory_name; done

see:

看:

回答by David W.

You have to use BASH? What about Perl or Kornshell? The problem here is that Bash doesn't have hash keyed arrays (Kornshell and Perl do). That means there's no simple way to track what files go where. Imagine in Perl:

你一定要用BASH吗?Perl 或 Kornshell 怎么样?这里的问题是 Bash 没有散列键控数组(Kornshell 和 Perl 有)。这意味着没有简单的方法来跟踪哪些文件去了哪里。在 Perl 中想象一下:

my %directoryB;   #Hash that contains files to move to Directory B
my %directoryC;   #Hash that contains files to move to Directory C

open (TEXT_FILE_B, "textFileB") or die qq(Can't open "textFileB");
while (my $line = <TEXT_FILE_B>) {
    chomp $line;
    $directoryB{$line} = 1;
}
close TEXT_FILE_B;

open (TEXT_FILE_C, "textFileC") or die qq(Can't open "textFileC");
while (my $line = <TEXT_FILE_C>) {
    chomp $line;
    $directoryC{$line} = 1;
}
close TEXT_FILE_C;

The above lines create two hashes. One for files that need to be moved to Directory B and one for files that need to be moved to Directory C. Now, all I have to do is look at my hash and decide:

以上几行创建了两个哈希。一个用于需要移动到目录 B 的文件,另一个用于需要移动到目录 C 的文件。现在,我所要做的就是查看我的哈希值并决定:

foreach my $file (@directory) { #A little cheating here...
   if (exists $directoryB{$file}) {
       move ($file, $directoryB);
   } elsif (exists $directoryC{$file}) {
       move ($file, $directoryC)
}

My if statements can now look to see if a key has been defined in that hash. If it has, I know the file can be moved into that directory. I only have to read the two text files once. After that, my two hashes will store which files move to one directory and which to the other.

我的 if 语句现在可以查看是否在该散列中定义了一个键。如果有,我知道可以将文件移动到该目录中。我只需要阅读这两个文本文件一次。之后,我的两个散列将存储哪些文件移动到一个目录,哪些文件移动到另一个。



However, we don't have hashes, so we'll use grepto see if the file name is in the directory. I'll assume that you have one file name on each line.

但是,我们没有哈希值,因此我们将使用它grep来查看文件名是否在目录中。我假设每一行都有一个文件名。

ls | while read file
do
   if grep -q "^${file}$" textFileB
   then
       mv $file $directoryB
   elif grep -q "^${file}$" textFileC
   then
       mv $file $directoryC
   fi
done

The grep -qwill search your two text files to see if the matching file is there. If it is, it'll move the file to that directory. It's not very efficient since it has to search the entire text file each and every time. However, it's pretty efficient, and you're only talking about 10,000 files, so the whole operation should only take a few minutes.

grep -q会搜索你的两个文本文件,看看是否匹配的文件是存在的。如果是,它会将文件移动到该目录。它不是很有效,因为它每次都必须搜索整个文本文件。但是,它非常有效,而且您只是在谈论 10,000 个文件,因此整个操作应该只需要几分钟。