我需要添加" hallo"在给定目录中的扩展名之前的每个文件名的末尾。但我的代码没有输出。 echo语句没有输出,文件名也没有改变
global $post;
$count = array(); // define $count as array variable
$args = array( 'post_type' => 'testimonial' 'posts_per_page' => -1, 'offset'=> 1);
$myposts = get_posts( $args );
foreach ( $myposts as $post ) : setup_postdata( $post );
// push rating value inside the $count array
$count[] = get_post_meta($post->ID, 'rating', true);
endforeach;
wp_reset_postdata();
$add = array_sum($count); // You can use this variable outside also.
echo $add; // print total rating.
echo $add/count($count) // Print average
答案 0 :(得分:2)
使用bash,可以简化:
for f in *;do
echo "$f" "${f%.*}hallo.${f##*.}"
done
示例:
$ ls -all
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file1.txt
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file2.txt
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file3.txt
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file4.txt
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file5.txt
$ for f in *;do mv -v "$f" "${f%.*}hallo.${f##*.}";done
'file1.txt' -> 'file1hallo.txt'
'file2.txt' -> 'file2hallo.txt'
'file3.txt' -> 'file3hallo.txt'
$ ls -all
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file1hallo.txt
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file2hallo.txt
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file3hallo.txt
这是有效的,因为${f%.*}
返回没有扩展名的文件名 - 从末尾(向后)删除所有(*)到第一个/最短找到的点。
另一方面,这一个${f##*.}
删除从开头到找到最长点的所有内容,只返回扩展名。
要克服注释中指出的无扩展文件问题,您可以执行以下操作:
$ for f in *;do [[ "${f%.*}" != "${f}" ]] && echo "$f" "${f%.*}hallo.${f##*.}" || echo "$f" "${f%.*}hallo"; done
file1.txt file1hallo.txt
file2.txt file2hallo.txt
file3.txt file3hallo.txt
file4 file4hallo
file5 file5hallo
如果文件没有扩展名,那么这将是真实的"${f%.*}" == "${f}"
答案 1 :(得分:1)
for file in $ls
这将扩展名为ls
的shell变量,将其内容拆分为单词,将这些单词中找到的任何通配符展开为匹配文件列表,然后迭代结果。但是没有定义ls
变量,所以它扩展为空,循环永远不会运行。我认为您正在尝试迭代ls
命令的输出;其语法是for file in $(ls)
。但是你不应该这样做,因为文件名可以包含空格和制表符,换行符和通配符以及各种其他有趣的字符,这些字符可以使迭代...除了文件名列表之外的其他内容。请参阅BashFAQ条目'Why you shouldn't parse the output of ls(1)'。
您应该使用的是for file in *
。 *
扩展为匹配文件列表(当前目录中的所有可见文件),然后该列表不会以任何方式混乱,只是直接迭代。唯一可能的问题是,如果没有任何匹配,则跳过扩展,并且循环运行一次,file
设置为" *"。
echo $file
当使用一个没有双引号的变量时,它会经历上面描述的单词拆分和通配符扩展过程。通常,没有任何反应。有时会发生奇怪和意外的事情。使用双引号,例如echo "$file"
。
for f in $file
for ... in ...
语句迭代单词,而不是字符。 shell没有特别好的方法来迭代字符串中的字符,但您可以使用for ((i=0; i<${#file}; i++)); do
迭代字符数字,然后使用"${file:$i:1}"
获取单个字符。
哦,for (( ))
和${var:start:length}
构造是所有shell中都不可用的bash扩展。如果您想在脚本中使用其中一个或两个,请确保使用特定于bash的shebang行(#!/bin/bash
或#!/usr/bin/env bash
)启动它。
if [ $f -eq $dot ];
同样,双引号变量引用以避免在变量包含空格或通配符时出现混乱,或者为空。此外,在[ ]
测试中,-eq
运算符执行数字比较而不是字符串比较;如果你给它不是有效数字的字符串,它会给出错误。对于字符串比较,请改用=
。此外,在行的末尾不需要分号(好吧,除了case
的末尾之外的一些地方)。如果then
位于同一行,则您在此处使用分号,但如果它位于下一行,则不会使用分号。
count=$count+$f
此处的+
将作为文字字符插入变量值中。要附加两个变量,只需使用count="$count$f"
之类的内容。 (注意:这实际上是少数几个可以放弃双引号的地方之一。但我仍然建议使用它们,因为它很难跟踪它的位置。安全且不在哪里,所以总是双重引用你的变量要容易得多。)
mv $file $count
再次,双引号。此外,在运行任何类型的自动批量重命名/移动时,如果命名冲突(或错误),您应始终使用mv -n
或mv -i
以防止覆盖文件或其他任何事情发生。
实际上,当我第一次运行这样的mass-mv脚本时,我喜欢在活动命令之前添加echo
(例如echo mv -n "$file" "$count"
)所以我可以做一个在我删除echo
并运行它之前,请确保它能够按照我的预期进行操作。