sed /PATTERN/SUB/ $VAR?

sed /PATTERN/SUB/ $VAR?

我正在重命名一些文件。

这有效:
ls | while IFS= read -r line; do name=$(echo $line | sed -e 's/\(.*\)/\1.jpg/') && mv $line $name; done

没关系,但我想让它更简洁,例如:
ls | while IFS= read -r line; do name=$(sed -e 's/\(.*\)/\1.jpg/' $line) && mv $line $name; done

后一个示例和各种类似的尝试将文件传递到 sed 而不是变量的值。

使用 ˋ $lineˋ 和$($line)两者都会导致尝试执行该文件。虽然"$line"'line'with 和 without的变体<都会导致文件被读入。这是怎么回事?该$line变量可以直接与 sed 一起使用以实现此目的吗?

答案1

好像您只想附加.jpg到当前目录中所有文件名的末尾。如果是这样的话,那么还有更简单的方法:

for f in ./*; do
  mv -- "$f" "$f.jpg"
done

确保--以破折号 ( -) 开头的文件名不会被解释为mv.但这在这里不是问题,因为我们还确保通过在循环中使用始终在开头$f具有路径。././*

的输出ls用于肉眼阅读,通常不适合像您一样发送到 while-read-loop 中。

是的,在第二个示例 ( sed -e 's/\(.*\)/\1.jpg/' $line) 中,文件的内容将由 读取sed。而使用 Bash,您就可以做到sed '...' <<<"$line"这一点。该<<<"string"构造是一个 Bash 扩展(至少在ksh和中也可用zsh),称为“here-string”,它将标准输入上的字符串传递给命令。

答案2

您可以使用这里字符串语法<<<

ls | while IFS= read -r line
do
  name=$(sed 's/\(.*\)/\1.jpg/' <<< $line) && mv "$line" "$name"
done

请注意,解析 的输出ls(也不使用不带引号的变量)不被认为是一个好主意。

还有一个工具名称rename(如果目标只是重命名文件):

rename -n 's/$/.jpg/' *

删除-n从预览更改为实际重命名的标志。

相关内容