我有一个RedHat linux框,我过去编写了一个脚本,用于将文件从一个位置移动到另一个位置,并在文件正文中使用特定文本。
我通常每年只会写一次脚本,所以每年我都会忘记越来越多......那就是说,
去年我编写了这个脚本并使用它并且它有效。
出于某种原因,我今天无法让它工作,我知道这是一个简单的问题,我甚至不应该寻求帮助,但出于某种原因,我今天没有正确地看待它。
这是脚本。
ls -1 /var/text.old | while read file
do
grep -q "to.move" $file && mv $file /var/text.old/TBD
done
我列出了/var/text.old目录中的所有文件。 我在读每个文件 然后,我正在为“to.move”而努力,并将结果挖空 然后我将生成的找到的文件移动到文件夹/var/text.old/TBD
我是管理员,我拥有上述文件和文件夹的权利。 我可以看到每个文件中的数据 我可以手动mv他们 我使用pwd来获取目录的正确拼写。
如果有人能帮助我看看我在这里失踪的那些真正能让我感到满意的事情。
提前致谢。
更新:
我需要移动的文件没有空格。
我得到的错误如下:
grep:9829563.msg:没有这样的文件或目录
注意:文件“982953.msg”是我需要移动的文件之一。 另请注意:我在列出的目录中的每个文件都收到此错误。
答案 0 :(得分:0)
你没有发布任何错误,但我会猜测并说你有一个带有空格或特殊shell字符的文件名。
假设你有3个文件,ls -1
给了我们:
hello
world
hey there
现在,while
分割了特殊$IFS
变量的值,默认情况下设置为<space><tab><newline>
。
因此,不是像预期的那样循环3个值(hello
,world
和hey there
),而是循环遍历 4 值(hello
, world
,hey
和there
)。
要解决这个问题,我们可以做两件事:
将IFS
设置为仅换行:
IFS="
"
ls -1 /var/text.old | while read file
...
一般来说,我喜欢在脚本开头将IFS
设置为换行符,因为我认为这有点“更安全”,但对此的看法可能会有所不同。
但更好的是不解析ls
的输出,并使用for
:
for file in /var/text.old/*`; do
这不会分叉任何外部进程(从ls
到while
的管道开始2),并且在其他方面表现得“不那么令人惊讶”。 See here for some examples
第二个问题是你没有引用$file
。出于同样的原因,您应该始终使用双引号引用路径名:"$file"
。如果$file
有空格(或特殊的shell字符,例如*
),则命令的含义会发生变化:
file=hey\ *
mv $file /var/text.old/TBD
变为:
mv hey * /var/text.old/TBD
显然非常与您的意图不同!你的意图是:
mv "hey *" /var/text.old/TBD