我想从文件中更改文件名后缀(使用bash脚本),但有时会有一个句点,一些句子有两个。
现在我用它:
new_file=`echo ${file} | sed 's/\(.*\.log.*\)'${suf}'/\1.'${num}'/'`
其中'new_file'是新文件名,'file'是原始文件名,'$ {suf}'是文件的后缀,$ {num}是新文件名。
所以 some.log 必须成为 some.log.1 , some.log.1 必须成为 some.log。 2 。使用我的代码 some.log 变为 some.log.1 ,但 some.log.1 仍然是 some.log.1 < / em>的
我希望我足够清楚。我很感激任何建议(甚至不使用sed)。
更新
@paxdiablo。我认为测试出了问题。
现在我使用这段代码作为测试;
#!/usr/bin/bash
shft() {
for suff in {6..1} ; do
if [[ -f "$1.${suff}" ]] ; then
((nxt = suff + 1))
echo Moving "$1.${suff}" to "$1.${nxt}"
mv -f "$1.${suff}" "$1.${nxt}"
fi
done
echo Moving "$1" to "$1.1"
mv -f "$1" "$1.1"
}
clear
folder=~/logs/*.log
for i in {1..20}; do
echo ${i}> ~/logs/some.log
for fspec in ${folder} ; do
shft "${fspec}"
done
done
现在每件事情都很好。对不起,感到困惑。
答案 0 :(得分:5)
如果您要翻转日志文件,并且根据您需要获得的复杂程度,我之前使用了以下细分:
#!/usr/bin/bash
# rollover.sh
# Rolls over log files in the current directory.
# *.log.8 -> *.log.9
# *.log.7 -> *.log.8
# : : :
# *.log.1 -> *.log.2
# *.log -> *.log.1
shft() {
# Change this '8' to one less than your desired maximum rollover file.
# Must be in reverse order for renames to work (n..1, not 1..n).
for suff in {8..1} ; do
if [[ -f "$1.${suff}" ]] ; then
((nxt = suff + 1))
echo Moving "$1.${suff}" to "$1.${nxt}"
mv -f "$1.${suff}" "$1.${nxt}"
fi
done
echo Moving "$1" to "$1.1"
mv -f "$1" "$1.1"
}
for fspec in *.log ; do
shft "${fspec}"
#date >"${fspec}" #DEBUG code
done
虽然您只需更改suff
for
循环以允许更多内容,但这会自动将日志文件翻转到版本9。
添加DEBUG
以便自动创建新文件以进行测试,以下脚本显示了它的实际效果:
pax> touch qq.log ; ./rollover.sh
Moving "qq.log" to "qq.log.1"
pax> touch "has spaces.log" ; ./rollover.sh
Moving "has spaces.log" to "has spaces.log.1"
Moving "qq.log.1" to "qq.log.2"
Moving "qq.log" to "qq.log.1"
pax> ll *log*
-rw-r--r-- 1 pax None 30 2010-09-11 20:39 has spaces.log
-rw-r--r-- 1 pax None 0 2010-09-11 20:39 has spaces.log.1
-rw-r--r-- 1 pax None 30 2010-09-11 20:39 qq.log
-rw-r--r-- 1 pax None 30 2010-09-11 20:38 qq.log.1
-rw-r--r-- 1 pax None 0 2010-09-11 20:38 qq.log.2
这个脚本的优点在于它可以轻松配置以处理大量历史记录(通过更改{8..1}
位),使用空格处理名称,并在日志文件丢失时相对健壮地处理间隙。 / p>
答案 1 :(得分:2)
要轮换日志,您应该使用logrotate。
如果你不能依赖logrotate,那么这就是shell中的一种方式。为了简单起见,我假设在脚本运行时没有其他任何内容(包括脚本的另一个实例)会尝试重命名日志文件。
最简单的方法是在实际将日志N重命名为N + 1之前递归重命名日志N + 1。 shell可以执行所有必要的算术,这里不需要sed
。请注意,虽然在POSIX shell中可以使用递归函数,但除了位置参数之外没有局部变量(许多shell提供局部变量作为扩展)。
#!/bin/sh
## Move "$1.$2" to "$1.$(($2+1))", first rotating the target as well.
rotate () {
if [ -e "$1.$(($2+1))" ]; then rotate "$1" $(($2+1)); fi
mv -- "$1.$2" "$1.$(($2+1))"
}
for x; do
## Break each argument into FILE.NUMBER or just FILE.
suffix=${x##*.}
case $suffix in
*[!0-9]*)
if [ -e "$x.0" ]; then rotate "$x" 0; fi
mv -- "$x" "$x.0";;
*) rotate "${x%.*}" "$suffix";;
esac
done
关于你写的内容,请注意echo ${file}
有两个原因:最重要的是,如果${file}
包含任何特殊字符(如空格),shell会解释它们;另外,对于一些shell,echo
本身将解释反斜杠,可能还有一个前导-
。所以你应该总是写printf %s "$file"
。