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

发布于 2024-11-18 07:55:02 字数 731 浏览 4 评论 0原文

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

伪代码:

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


将文件从目录 A 移动到目录 C

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

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

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

我可以只说明文本文件名吗?如果可以的话,文件必须采用什么格式? 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

顺便说

一句 Mac OSX 10.6.8(雪豹) 苹果终端 v.2.1.2 / 273.1 重击 3.2

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.

Pseudocode:

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

for file in textfileC:
move file from directory A to directory 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).

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]

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

夏尔 2024-11-25 07:55:02
cat file-list.txt | while read i; do
   # TODO: your "mv" command here.  "$i" will be a line from
   # the text file.
done
cat file-list.txt | while read i; do
   # TODO: your "mv" command here.  "$i" will be a line from
   # the text file.
done
此生挚爱伱 2024-11-25 07:55:02

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

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

月野兔 2024-11-25 07:55:02

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

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

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
小耗子 2024-11-25 07:55:02

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

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

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

cat deleteduser | while read i;  do mv -vv $i ../deleted_user; done; 
deleteuser= user name list
../deleted_user= destination dir
時窥 2024-11-25 07:55:02

你必须使用 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;

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

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

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


但是,我们没有哈希值,因此我们将使用 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

grep -q 将搜索两个文本文件以查看是否存在匹配的文件。如果是,它会将文件移动到该目录。它的效率不是很高,因为它每次都必须搜索整个文本文件。不过,它的效率相当高,而且您只讨论了 10,000 个文件,因此整个操作只需要几分钟。

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:

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:

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.


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

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 -q will 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.

挖鼻大婶 2024-11-25 07:55:02

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

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

参阅:

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

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

see:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文