如何使用 bash 脚本取消 tar 目录中每种类型的 tar 文件?
How to untar every type of tar file in a directory with bash script?
我是为自动化任务编写 bash 脚本的初学者,我正在尝试取消 tar 一个目录中的所有 tar 文件(也有很多方法许多人手工完成)以获得一堆源代码文件。它们都是 *.tar.gz、*.tar.xz 或 *.tar.bz2.
类型
这是我正在执行的 Linux from 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目录中的所有内容并创建单独的目录,但它却退出并出现此错误:
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 更改为正在通过我的 for 构造的每个文件。我将如何为此编写脚本,尤其是因为有不同类型的文件?
要让您的脚本以最少的更改工作,请在需要变量值时使用 $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
如果我们只列出我们想要循环的三种类型的文件,我们甚至可以摆脱错误消息。那就没办法打else了。
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 {} \;
我是为自动化任务编写 bash 脚本的初学者,我正在尝试取消 tar 一个目录中的所有 tar 文件(也有很多方法许多人手工完成)以获得一堆源代码文件。它们都是 *.tar.gz、*.tar.xz 或 *.tar.bz2.
类型这是我正在执行的 Linux from 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目录中的所有内容并创建单独的目录,但它却退出并出现此错误:
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 更改为正在通过我的 for 构造的每个文件。我将如何为此编写脚本,尤其是因为有不同类型的文件?
要让您的脚本以最少的更改工作,请在需要变量值时使用 $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
是一个重量级的工具。您可以使用 [[
和 ==
.
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
如果我们只列出我们想要循环的三种类型的文件,我们甚至可以摆脱错误消息。那就没办法打else了。
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 {} \;