在unix脚本中获取最高扩展值
我需要创建扩展名为file.1、file.2、file.3的新文件,然后检查是否存在具有特定编号的文件并创建文件。(n+1),其中n是现有文件中最高的编号。我尝试使用basename获取扩展名,但它不想获取两个文件在unix脚本中获取最高扩展值,unix,Unix,我需要创建扩展名为file.1、file.2、file.3的新文件,然后检查是否存在具有特定编号的文件并创建文件。(n+1),其中n是现有文件中最高的编号。我尝试使用basename获取扩展名,但它不想获取两个文件 file=`basename $file.*` ext=${file##*.} 仅当我输入整个文件名(如$file.3时,它才起作用。如果保证文件名中没有换行符,例如,您可以使用标准的unix文本处理工具: printf '%s\n' file.* | #full list sed
file=`basename $file.*`
ext=${file##*.}
仅当我输入整个文件名(如
$file.3
时,它才起作用。如果保证文件名中没有换行符,例如,您可以使用标准的unix文本处理工具:
printf '%s\n' file.* | #full list
sed 's/.*\.//' | #extensions
grep '^[0-9][0-9]*$' | #numerical extensions
awk '{ if($0>m) m=$0} END{ print m }' #get maximum
如果保证文件名中不包含换行符,例如,您可以使用标准unix文本处理工具:
printf '%s\n' file.* | #full list
sed 's/.*\.//' | #extensions
grep '^[0-9][0-9]*$' | #numerical extensions
awk '{ if($0>m) m=$0} END{ print m }' #get maximum
这是我的看法 您完全可以在标准awk中执行此操作
$ awk '{ext=FILENAME;sub(/.*\./,"",ext)} ext>n&&ext~/^[0-9]+$/{n=ext}{nextfile} END {print n}' *.*
分门别类,便于阅读:
$ awk '
{
# Capture the extension...
ext=FILENAME
sub(/.*\./,"",ext)
}
# Then, if we have a numeric extension that is bigger than "n"...
ext > n && ext ~ /^[0-9]+$/ {
# let "n" be that extension.
n=ext
}
{
# We aren't actually interested in the contents of this file, so move on.
nextfile
}
# No more files? Print our result.
END {print n}
' *.*
这里的想法是,我们将逐步浏览文件名列表,并让awk执行所有处理来捕获和“排序”扩展名。(我们并不是真正的排序,我们只是在通过文件时记录最高的数字。)
此解决方案有几个限制条件:
ext
变量,您可以直接修改FILENAME
。为了提高可读性,我加入了它nextfile
命令相当标准,但并不通用。如果您有一台非常旧的计算机,或者正在运行各种各样的unix,则可能不包括nextfile
。(我不认为这是个问题。)另一种可能更容易的选择是直接在POSIX shell中实现相同的逻辑:
$ n=0; for f in *.*; do ext=${f##*.}; if expr "$ext" : '[0-9][0-9]*$' >/dev/null && [ "$ext" -gt "$n" ]; then n="$ext"; fi; done; echo "$n"
或者,为了便于阅读(或编写脚本),再次进行了以下操作:
这将使用for循环遍历所有文件,捕获扩展名,确保其为数字,确定其是否大于“n”,并记录是否大于“n”,然后打印其结果
它不需要管道,也不需要外部工具,除了expr
,这是每个系统上可用的POSIX.1工具
此解决方案的一个限制条件是,如果没有扩展名为的文件(即
*.
不返回任何文件),此脚本将错误地报告编号最高的扩展名为0
。你当然可以很容易地处理这件事,但我想我应该提一下。以下是我对这件事的看法
您完全可以在标准awk中执行此操作
$ awk '{ext=FILENAME;sub(/.*\./,"",ext)} ext>n&&ext~/^[0-9]+$/{n=ext}{nextfile} END {print n}' *.*
分门别类,便于阅读:
$ awk '
{
# Capture the extension...
ext=FILENAME
sub(/.*\./,"",ext)
}
# Then, if we have a numeric extension that is bigger than "n"...
ext > n && ext ~ /^[0-9]+$/ {
# let "n" be that extension.
n=ext
}
{
# We aren't actually interested in the contents of this file, so move on.
nextfile
}
# No more files? Print our result.
END {print n}
' *.*
这里的想法是,我们将逐步浏览文件名列表,并让awk执行所有处理来捕获和“排序”扩展名。(我们并不是真正的排序,我们只是在通过文件时记录最高的数字。)
此解决方案有几个限制条件:
ext
变量,您可以直接修改FILENAME
。为了提高可读性,我加入了它nextfile
命令相当标准,但并不通用。如果您有一台非常旧的计算机,或者正在运行各种各样的unix,则可能不包括nextfile
。(我不认为这是个问题。)另一种可能更容易的选择是直接在POSIX shell中实现相同的逻辑:
$ n=0; for f in *.*; do ext=${f##*.}; if expr "$ext" : '[0-9][0-9]*$' >/dev/null && [ "$ext" -gt "$n" ]; then n="$ext"; fi; done; echo "$n"
或者,为了便于阅读(或编写脚本),再次进行了以下操作:
这将使用for循环遍历所有文件,捕获扩展名,确保其为数字,确定其是否大于“n”,并记录是否大于“n”,然后打印其结果
它不需要管道,也不需要外部工具,除了expr
,这是每个系统上可用的POSIX.1工具
此解决方案的一个限制条件是,如果没有扩展名为的文件(即
*.
不返回任何文件),此脚本将错误地报告编号最高的扩展名为0
。当然,你可以很容易地处理这个问题,但我想我应该提一下。谢谢你的回答,我提出了一个非常类似的简单想法,我想介绍一下:
for i in file.*; do
#reading the extensions
ext=${i##*.}
if [ "$ext" -gt "$n" ];
then
#increasing n
n=$((n+1))
fi
done
那么如果我们想得到一个大于n的数
until [[ $a -gt "$n" ]]; do
a=$((a+1))
done
最后,a比文件扩展名的数量大一个数字。因此,如果有三个文件:file.1 file.2 file.3,则返回的值将为4。感谢所有的回答,我提出了一个非常相似且简单的想法,我想介绍一下:
for i in file.*; do
#reading the extensions
ext=${i##*.}
if [ "$ext" -gt "$n" ];
then
#increasing n
n=$((n+1))
fi
done
那么如果我们想得到一个大于n的数
until [[ $a -gt "$n" ]]; do
a=$((a+1))
done
最后,a比文件扩展名的数量大一个数字。因此,如果有三个文件:file.1 file.2 file.3,则返回的值将为4。此脚本返回的唯一内容是
txt
,此文件夹中还有其他文件:file。file.1 file.2 file.3 file.txt。编辑:哦,我的错。txt也被考虑在内,我只需要数字。@codddeer123添加了一个仅用于数字的过滤器。你需要更清楚地表达你的问题。我不知道为什么,但不幸的是,这对我不起作用<代码>➜ dir ls file.1 file.2 file.3 script.sh➜ dir./script.sh它不返回任何内容。@codddeer123对不起,添加的grep过滤器是错误的。普通grep没有+
。您需要-P或^[0-9][0-9]*$
使用经典grep。它现在应该可以工作了。@PSkocik-实际上它不是-P
(在GNU grep中启用Perl风格的RE),而是egrep
或grep-E
。当然,如果您有-P
,您可以使用它,但是egrep
更便于移植,并且对于这样的情况也同样有用。此脚本返回的唯一内容是txt
,此文件夹中还有其他文件:fi