【问题标题】:Bash command ls ordering optionsBash 命令 ls 排序选项
【发布时间】:2017-08-23 18:55:56
【问题描述】:

这里是新的(和编码)。我正在编写一个简单的 bash 脚本,它可以帮助我在当前目录的所有文件中将一个字符更改为另一个字符。代码如下:

#!/bin/bash
#this script changes characters in all files of the current directory

NUM=$(ls -1 | wc -l | awk '{print $1}')

echo "There are $NUM files in this folder."
echo "Changing $1 to $2 in all their names..."
echo "Done! Here's what happened:"

for i in $(seq 1 $NUM)
do
    OLDNAME=$(ls -1 | head -$i | tail -1)
    NEWNAME=$(ls -1 | head -$i | tail -1 | sed -e "s/${1}/${2}/g")
    mv -v "$OLDNAME" "$NEWNAME"
done

因此,如果我写./ccin.sh " " "_",它应该将当前目录中所有文件的名称中的所有空格都更改为下划线。但事实并非如此,我认为这是ls 的错。 for 循环跳过了一些文件,因为ls 每次mv 有效地修改其中一个文件时都会更改文件排序的顺序。所以我需要以一种不依赖于“最后修改”属性的方式来隔离文件的名称。我想到了文件大小,但如果有两个大小相同的文件,这将不起作用——例如,我正在一个充满空文件的目录上尝试此代码。

有没有办法使用ls 对文件进行排序,以使它们保持与mv 修改其名称时相同的顺序?

【问题讨论】:

    标签: bash shell ls


    【解决方案1】:

    您可以尝试用这个替换您的 for 循环:

    find . -type f | while read file
    do
        OLDNAME="$file"
        NEWNAME=`echo $file| sed -e "s/${1}/${2}/g"`
        mv -v "$OLDNAME" "$NEWNAME"
    done
    

    您不必多次运行 ls 来重命名文件,而是只运行一次 find 并遍历结果

    【讨论】:

    • 谢谢!这要简单得多。
    • 是的,但我刚刚意识到它不适用于带空格的文件名,让我来解决
    • 也许使用awk
    • 从不使用for i in $(ls anything),见Bash Pitfalls #1
    • @piarston,这应该是一个 bash 脚本练习
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 2016-04-21
    相关资源
    最近更新 更多