我是编写用于自动执行任务的bash脚本的初学者,我正在尝试解决一堆目录中的所有tar文件(有很多东西要手工完成)以获取一堆源代码文件。它们都是* .tar.gz,* .tar.xz或* .tar.bz2。
这是针对Linux正在进行的Scratch LFS安装(我是第一个计时器),除了使用bash脚本之外,我不确定如何自动执行此任务。我的小脚本的代码如下所示。
#!/bin/bash
for afile in 'ls -1'; do
if [ 'afile | grep \"\.tar\.gz\"' ];
then
tar -xzf afile
elif [ 'afile | grep \"\.tar\.xz\"' ]
then
tar -xJf afile
elif [ 'afile | grep \"\.tar\.xz\"' ]
then
tar -xjf afile
else
echo "Something is wrong with the program"
fi
done;
我希望它解开目录中的所有内容并创建单独的目录,但它会退出并显示以下错误:
tar (child): afile: Cannot open: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now
显然它认为afile是实际的文件,但我不知道如何改变文件是通过我的构造的每个文件。我如何为此编写脚本,特别是因为有不同类型的文件?
要使脚本能够以最小的更改工作,请在需要变量值时使用$afile
。美元符号作为变量参考;否则你只需要得到文字字符串'afile'
。也摆脱方括号,而不是echo
变量到grep
。
for afile in `ls -1`; do
if echo "$afile" | grep '\.tar\.gz'
then
tar -xzf "$afile"
elif echo $afile | grep '\.tar\.xz'
then
tar -xJf "$afile"
elif echo "$afile" | grep '\.tar\.bz2'
then
tar -xjf "$afile"
else
echo "Something is wrong with the program"
fi
done
既然你是一个bash初学者,那么让我们看看你可以编写脚本的各种其他方法。我会做一些改进。一个,you shouldn't loop over ls
。你可以通过循环*
得到同样的东西。其次,grep
是一个重量级的工具。您可以使用内置的shell结构(如[[
和==
)进行一些简单的字符串比较。
for afile in *; do
if [[ "$afile" == *.tar.gz ]]; then
tar -xzf "$afile"
elif [[ "$afile" == *.tar.xz ]]; then
tar -xJf "$afile"
elif [[ "$afile" == *.tar.bz2 ]]; then
tar -xjf "$afile"
else
echo "Something is wrong with the program"
fi
done
实际上,使用case
语句会更好。我们试试吧。还让我们用>&2
将错误消息回显给stderr。这总是一个好主意。
for afile in *; do
case "$afile" in
*.tar.gz) tar -xzf "$afile";;
*.tar.xz) tar -xJf "$afile";;
*.tar.bz2) tar -xjf "$afile";;
*) echo "Something is wrong with the program" >&2
esac
done
如果我们只列出我们想要循环的三种类型的文件,我们甚至可以摆脱错误消息。然后没有办法打败其他情况。
for afile in *.tar.{gz,xz,bz2}; do
case "$afile" in
*.tar.gz) tar -xzf "$afile";;
*.tar.xz) tar -xJf "$afile";;
*.tar.bz2) tar -xjf "$afile";;
esac
done
或者采用完全不同的方式:使用find
查找所有文件及其-exec
操作,为其找到的每个文件调用命令。这里{}
是它找到的文件的占位符。
find . -name '*.tar.gz' -exec tar -xzf {} \;
find . -name '*.tar.xz' -exec tar -xJf {} \;
find . -name '*.tar.bz2' -exec tar -xjf {} \;