Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
File 根据物品名称在终端中移动物品_File_Bash_Parsing_Terminal_Directory - Fatal编程技术网

File 根据物品名称在终端中移动物品

File 根据物品名称在终端中移动物品,file,bash,parsing,terminal,directory,File,Bash,Parsing,Terminal,Directory,编辑:我想这已经被成功地回答了,但我不能检查,直到稍后。我已经按照建议重新格式化了 问题:我有一系列文件,每个文件的名称都是XXXXNAME,其中XXXX是一些数字。我想将它们全部移动到名为XXXX的单独文件夹中,并将它们命名为NAME。我可以手动完成这项工作,但我希望通过将它们命名为XXXXNAME,我可以告诉Terminal(我认为这是正确的名称,但不是很确定)将它们移动到那里。差不多 mv*名称*/名称 但它把第一个案例中的所有东西都带到了那里,并将其反流到路径上 这是在某种形式的Linu

编辑:我想这已经被成功地回答了,但我不能检查,直到稍后。我已经按照建议重新格式化了

问题:我有一系列文件,每个文件的名称都是XXXXNAME,其中XXXX是一些数字。我想将它们全部移动到名为XXXX的单独文件夹中,并将它们命名为NAME。我可以手动完成这项工作,但我希望通过将它们命名为XXXXNAME,我可以告诉Terminal(我认为这是正确的名称,但不是很确定)将它们移动到那里。差不多

mv*名称*/名称

但它把第一个案例中的所有东西都带到了那里,并将其反流到路径上

这是在某种形式的Linux上,带有bash shell

在现实生活中,文件是0000GNUmakefile,具有顺序编号。作为我研究的一部分,我不得不对一个程序做很多类似但稍加修改的版本,以便在集群上编译和运行。编写一个程序来编辑所有的文件并将其放在正确的位置可能会更快,但我没有

这可能非常简单,如果我知道正确的词语,我应该能够自己找到答案。问题是,我没有接受过编程方面的正式培训,所以我不知道该怎么称呼这些东西来搜索它们。所以希望这能让我得到一个答案,也许下次我自己也知道如何找到类似问题的答案。有了我学过的基本编程,我相信我可以为自己编写一个程序,但我希望有一种简单的方法,只需使用终端中已有的功能即可。我可能不应该被允许玩这些东西


谢谢你的帮助!实际上,我可以用C和Python编写相当多的程序,但这在很大程度上是经过反复试验的,我仍然不知道在Terminal中我能做什么和不能做什么。

下面的脚本将为您完成这项工作。将脚本复制到远程计算机上的一个文件中(我们称之为sortfiles.sh)

在命令行中,do
chmod+x sortfiles.sh


使用
/sortfiles.sh
执行脚本只需打开终端应用程序,
cd
到包含要移动/重命名的文件的目录中,然后将这些命令复制并粘贴到命令行中

for file in [0-9][0-9][0-9][0-9]*; do
  dirName="${file%%*([^0-9])}"
  mkdir -p "$dirName"
  mv "$file" "$dirName/${file##*([0-9])}"
done
这假定要重命名和移动的所有文件都位于同一目录中。文件globbing还假定文件名开头至少有四位数字。如果有四个以上的数字,仍然会被捕获,但如果少于四个,则不会被捕获。如果少于四个,从第一行取下适当数量的
[0-9]
s

它不处理“NAME”(即您想要的新文件名)以数字开头的情况


有关bash中字符串操作的更多信息,请参阅。

实现这一点的方法有很多

我发现旧的备用程序
sed
awk
通常是最强大的

ls | sed -rne 's:^([0-9]{4})(NAME)$:mv -iv & \1/\2:p'
如果您对命令的外观感到满意,请使用管道将命令行穿过外壳:

ls | sed -rne 's:^([0-9]{4})(NAME)$:mv -iv & \1/\2:p' | sh
我将名称放在括号中,并使用了
\2
,这样,如果它的变化比示例所示的要大,您就可以使用正则表达式更好地处理文件名

要在
gawk
(GNU awk,大多数GNU/Linux发行版中的变体)中执行相同的操作:

与第一个示例一样,这将生成命令,如果您认为这些命令有意义,可以通过将
|sh
附加到行的末尾,通过管道将其传递到shell

注意,对于所有这些
mv
命令,我添加了
-I
-v
选项。这是为了保护你。阅读
mv
(在Linux终端中键入
manmv
)的手册页,看看您是否愿意将其忽略

另外,我假设这些行中的所有目录都已经存在。你没提到他们有没有。如果他们没有,这里有一个一行程序来创建目录

ls | sed -rne 's:^([0-9]{4})(NAME)$:mkdir -p \1:p' | sort -u
与其他命令一样,附加
|sh
以运行命令

我应该提到,通常建议使用
for
(在Tim的回答中)或
find
等结构,而不是解析
ls
的输出。这就是说,当您的文件名格式像
/[0-9]{4}word/
那样简单时,我发现快速
sed
一行代码就是最好的选择


最后,如果您所说的
NAME
实际上是指“任何字符串”而不是字面字符串“NAME”,那么在我上面的所有示例中,将
NAME
替换为
*

将第一段移到最后。从问题开始同样,我认为你仍然需要编写一些shell脚本来完成它。另外,更好地定义你的问题。什么是“名称”和“XXXX”?它们之间的界限是如何通过程序确定的?“XXXX”应该是任意字符的4位吗?请注意,此解决方案假定数字文件名前缀正好是4位数字。如果文件名或目录名中有空格,则此选项无效。根本问题在于初始的
find
命令。文件名中的任何空格都将被视为单独的文件。对于bash提供的开箱即用的简单字符串操作,启动echo和cut也很昂贵。如果
$dirName
已经存在,则会抛出错误,并且不能处理名称实际上是以数字开头的字符串的情况。即,
00019999
应移至
0001/9999
。请参阅我的更改。错误不会影响输出。关于数字的观点很好,我想在前面提到。您还可以使用
mkdir-p“$dirName”
,消除错误,正如ghoti所示。@l0b0-您会注意到我在回答中确实提到了这一点。然而,你在Greg的wiki上链接的那篇文章谈到了在各种情况下使用
ls
ls | gawk '/^[0-9]{4}NAME$/ {printf("mv -iv %s %s/%s\n", $1, substr($0,0,4), substr($0,5))}'
ls | sed -rne 's:^([0-9]{4})(NAME)$:mkdir -p \1:p' | sort -u