【问题标题】:whats the correct way to loop this循环这个的正确方法是什么
【发布时间】:2012-10-27 05:44:51
【问题描述】:

我有一个脚本,其中 inotifywait 被输送到执行以下逻辑的 while 循环中。

     cp "$S3"/2/post2.png "$S3";
     mv "$S3"/1/post1.png "$S3"/2/post2.png;
     cp "$S3"/3/post3.png "$S3";
     mv "S3"/post2.png "$S3"/3/post3.png;

以此类推......然后在脚本的末尾......

     mv "$dir"/$file "$S3"/1/post1.png

那条线代表一个新帖子,上面是旧帖子的轮换。

我可以将迭代一直手动编码到 100 次以上,但我希望更高效地编程并节省时间。

那么,有哪些正确的循环方式?

【问题讨论】:

  • 我不认为第四行是正确的...mv "$S3"/2/post2.png "$S3"/3/post3.png 也许?
  • 最旧的帖子会发生什么?是消失了还是为它创建了新目录$3/nnn
  • 您是否只是想将所有帖子编号移一位?倒过来怎么样?
  • 不清楚你的意思是什么。 shell 变量S3 似乎无关紧要,您可以通过删除它或在其位置指定一些短目录名称来简化问题。还要说明 /1/、/2/、/3/ 目录的用途。说出你想做什么。

标签: bash loops inotify


【解决方案1】:

我认为一个更好的机制会以相反的数字顺序列出"$S3" 中的目录,并安排像这样处理它们。目前尚不清楚这 100 个目录是否都存在或是否需要创建。我们假设目录 1..100 可能存在,并且目录 N 将始终且仅包含 postN.png

我假设文件路径中没有空格、换行符或其他尴尬的字符;这意味着ls 可以在没有太大风险的情况下使用。

for dirnum in $(cd "$S3"; ls */*.png | sed 's%/.*%%' | sort -nr)
do
    next=$(($dirnum + 1))
    mv "$S3/$dirnum/post$dirnum.png" "$S3/$next/post$next.png"
done

cd "$S3" 表示输出中没有包含可能很长的路径名; ls */*.png 列出了存在的文件; sed 删除文件名和斜杠,只留下包含文件的目录号列表;并且排序将目录以相反的数字顺序排列。

假设必要的目录已经存在,剩下的就很简单了。在移动文件之前添加[ -d "$S3/$next" ] || mkdir -p "$S3/$next" 并不难。显然,在循环之后你可以使用你的最终命令:

mv "$dir/$file" "$S3/1/post1.png"

请注意,我已将完整名称用双引号括起来;如果某些东西意外地获得空间,它通常会减少令人讨厌的意外。

【讨论】:

  • 太恶心了!你完全理解了这个问题,用有限的词只是代码!我对您的代码感到惊讶。你只是打开了我的思路......不仅在循环上,而且在管道上所有这些命令只是为了创建一个变量。完美无瑕!!谢谢leffler先生!
【解决方案2】:

试试这个:

for i in $(ls -r1 "$3"); do 
    mkdir -p "$3/$((i+1))"
    mv "$3/$i/post$i.png" "$3/$((i+1))/post$((i+1)).png"
done
mv "$dir"/$file "$S3"/1/post1.png

循环将以相反的顺序遍历所有目录并移动文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-06
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多