“文件名太长”的bash mv命令旧文件
#! /bin/sh -
cd /PHOTAN || exit
fn=$(ls -t | tail -n -30)
mv -f -- "${fn}" /old
所有我想要的待办事项是保持最近30个文件...但不能让过去的MV “文件名过长”问题“文件名太长”的bash mv命令旧文件
请帮忙”
符号"${fn}"
将所有文件名添加到单个参数字符串中,并用空格分隔。只是这一次,假设你不必担心带空格的文件名,你需要:
mv -f -- ${fn} /old
如果您有空格的文件名,开始解析,然后你有问题输出ls
命令。
但是,如果您不必担心文件名中的空格?
然后,正如我所说,你有大问题,从解析ls
的输出问题开始。
$ echo > 'a b'
$ echo > ' c d '
$
两个漂亮的文件名,其中包含空格。他们造成快乐的地狱。我即将假设你在Linux上或类似的东西。您需要使用bash
阵列,stat
命令,printf
,sort -z
,sed -z
。或者你应该简单地用空格来限制文件名;它可能更容易。
names=(*)
阵列names
包含每个文件名作为一个单独的数组元素,前缘和后缘和嵌入的空格都正确处理。
names=(*)
for file in "${names[@]}"
do printf "%s\0" "$(stat -c '%Y' "$file") $file"
done |
sort -nzr |
sed -nze '1,30s/^[0-9][0-9]* //p' |
tr '\0' '\n'
的for
环分别评估每个文件的修改时间,和结合了修改时间,空间,和文件名成一个字符串后跟一个空字节来标记串的结束。 sort
命令以数字方式对'行'进行排序,假设由于-z
选项导致行由空字节终止,并且最先放置最近的文件名。 sed
命令仅打印前30个'行'(文件名); tr
命令用空行替换空字节(但这样做会丢失文件名边界的标识)。
代码工作甚至用含有换行符的文件名,但只能在系统中sed
和sort
支持(非标准)-z
选项处理空终止输入“线” - 这意味着使用GNU sed
和sort
系统(即使在Mac OS X上找到的BSD sed
也没有,尽管Mac OS X sort
是GNU sort
并确实支持-z
)。
呃!该shell是为空间出现在文件名之间而不是文件名而设计的。
作为一个comment注意到BroSlow,如果你假设,那么代码可以更简单,更接近便携“在文件名中没有新行” - 但它仍然是棘手:
ls -t |
tail -30 |
{
list=()
while IFS='' read -r file
do list+=("$file")
done
mv -f -- "${list[@]}" /old
}
的需要使用IFS=''
,以便保留文件名中的前导空格和尾随空格(以及制表符)。
我注意到Korn shell不需要大括号,但Bash可以。
但是,如果您不必担心文件名中的空格? – Gabe 2014-09-06 03:37:26
然后你有重大问题!让我冥想吧;这是非常不愉快的,无论如何。你在Linux或其他类Unix平台上吗? – 2014-09-06 03:39:16
可以假定没有带有换行符的文件并解析'ls'输出。但为了完整性+1。 – BroSlow 2014-09-06 08:35:10