sed / awk - 删除文件名中的 space
sed / awk - remove space in file name
我正在尝试删除文件名中的空格并替换它们。
输入:
echo "File Name1.xml File Name3 report.xml" | sed 's/[[:space:]]/__/g'
然而输出
File__Name1.xml__File__Name3__report.xml
期望的输出
File__Name1.xml File__Name3__report.xml
如果没有描述文件名,这似乎是一个好的开始:
((?:\S.*?)?\.\w{1,})\b
( // start of captured group
(?: // non-captured group
\S.*? // a non-white-space character, then 0 or more any character
)? // 0 or 1 times
\. // a dot
\w{1,} // 1 or more word characters
) // end of captured group
\b // a word boundary
您必须查找 PCRE 模式如何转换为 shell 模式。或者它可以是来自 Python/Perl/PHP 脚本的 运行。
你可以使用 rename
:
rename --nows *.xml
这会将当前文件夹中 xml 个文件的所有空格替换为 _
。
有时它没有 --nows
选项,因此您可以使用搜索和替换:
rename 's/[[:space:]]/__/g' *.xml
如果您只想打印文件名而不编辑名称,最终您可以使用 --dry-run
。
你在问题的标题中命名为 awk
,是吗?
$ echo "File Name1.xml File Name3 report.xml" | \
> awk -F'.xml *' '{for(i=1;i<=NF;i++){gsub(" ","_",$i); printf i<NF?$i ".xml ":"\n" }}'
File_Name1.xml File_Name3_report.xml
$
-F'.xml *'
指示awk
在正则表达式上拆分,请求的扩展加上0个或多个spaces
- 循环
{for(i=1;i<=NF;i++)
对输入行被分割的所有字段执行 — 请注意,最后一个字段是空的(它是最后一个扩展名之后的内容),但是我们将考虑到这一点...
循环的 body
gsub(" ","_", $i)
将所有出现的 space 替换为当前字段中的下划线,由循环变量 i
索引
printf i<NF?$i ".xml ":"\n"
输出不同的东西,如果 i<NF
它是一个常规字段,所以我们附加扩展名和一个 space,否则 i
等于 NF
,我们只想用换行符终止输出行。
它并不完美,它在最后一个文件名后附加了一个 space。我希望这足够好...
▶ A D D E N D U M ◀
我想联系:
- 最后的小号space...
- 一些the issues reported by Ed Morton
- 推广提供给
awk
的扩展
为了实现这些目标,我决定将 scriptlet 包装在一个 shell 函数中,将 spaces 更改为下划线的命名为 s2u
$ s2u () { awk -F'\.'' *' -v ext="." '{
> NF--;for(i=1;i<=NF;i++){gsub(" ","_",$i);printf "%s",$i ext (i<NF?" ":"\n")}}'
> }
$ echo "File Name1.xml File Name3 report.xml" | s2u xml
File_Name1.xml File_Name3_report.xml
$
有点不同(更好?)'cs 它不特别打印最后一个字段,而是 special-cases 附加到每个字段的分隔符,但拆分扩展名的想法仍然存在。
假设您问的是如何重命名文件名,而不是删除因其他原因而使用的文件名列表中的空格,这是长而短的方法。漫长的道路使用 sed。简短的方法使用重命名。如果您不是要重命名文件,则您的问题很不清楚,应该修改。
如果目标是简单地获取 xml 文件名列表并使用 sed 更改它们,下面的示例是如何做到这一点。
目录内容:
ls -w 2
bob is over there.xml
fred is here.xml
greg is there.xml
cd [directory with files]
shopt -s nullglob
a_glob=(*.xml);
for ((i=0;i< ${#a_glob[@]}; i++));do
echo "${a_glob[i]}";
done
shopt -u nullglob
# output
bob is over there.xml
fred is here.xml
greg is there.xml
# then rename them
cd [directory with files]
shopt -s nullglob
a_glob=(*.xml);
for ((i=0;i< ${#a_glob[@]}; i++));do
# I prefer 'rename' for such things
# rename 's/[[:space:]]/_/g' "${a_glob[i]}";
# but sed works, can't see any reason to use it for this purpose though
mv "${a_glob[i]}" $(sed 's/[[:space:]]/_/g' <<< "${a_glob[i]}");
done
shopt -u nullglob
结果:
ls -w 2
bob_is_over_there.xml
fred_is_here.xml
greg_is_there.xml
globbing 是你想要的,因为名称中有空格。
然而,这确实是一个复杂的解决方案,实际上您需要做的只是:
cd [your space containing directory]
rename 's/[[:space:]]/_/g' *.xml
就这样,大功告成。
另一方面,如果您正在尝试创建一个文件名列表,您肯定需要通配方法,如果您只修改语句,它也会执行您想要的操作,也就是说,只是使用 sed 更改输出文件名。
如果您的目标是为了输出而更改文件名,而不是重命名实际文件:
cd [directory with files]
shopt -s nullglob
a_glob=(*.xml);
for ((i=0;i< ${#a_glob[@]}; i++));do
echo "${a_glob[i]}" | sed 's/[[:space:]]/_/g';
done
shopt -u nullglob
# output:
bob_is_over_there.xml
fred_is_here.xml
greg_is_there.xml
我正在尝试删除文件名中的空格并替换它们。
输入:
echo "File Name1.xml File Name3 report.xml" | sed 's/[[:space:]]/__/g'
然而输出
File__Name1.xml__File__Name3__report.xml
期望的输出
File__Name1.xml File__Name3__report.xml
如果没有描述文件名,这似乎是一个好的开始:
((?:\S.*?)?\.\w{1,})\b
( // start of captured group
(?: // non-captured group
\S.*? // a non-white-space character, then 0 or more any character
)? // 0 or 1 times
\. // a dot
\w{1,} // 1 or more word characters
) // end of captured group
\b // a word boundary
您必须查找 PCRE 模式如何转换为 shell 模式。或者它可以是来自 Python/Perl/PHP 脚本的 运行。
你可以使用 rename
:
rename --nows *.xml
这会将当前文件夹中 xml 个文件的所有空格替换为 _
。
有时它没有 --nows
选项,因此您可以使用搜索和替换:
rename 's/[[:space:]]/__/g' *.xml
如果您只想打印文件名而不编辑名称,最终您可以使用 --dry-run
。
你在问题的标题中命名为 awk
,是吗?
$ echo "File Name1.xml File Name3 report.xml" | \
> awk -F'.xml *' '{for(i=1;i<=NF;i++){gsub(" ","_",$i); printf i<NF?$i ".xml ":"\n" }}'
File_Name1.xml File_Name3_report.xml
$
-F'.xml *'
指示awk
在正则表达式上拆分,请求的扩展加上0个或多个spaces- 循环
{for(i=1;i<=NF;i++)
对输入行被分割的所有字段执行 — 请注意,最后一个字段是空的(它是最后一个扩展名之后的内容),但是我们将考虑到这一点...
循环的 bodygsub(" ","_", $i)
将所有出现的 space 替换为当前字段中的下划线,由循环变量i
索引
printf i<NF?$i ".xml ":"\n"
输出不同的东西,如果i<NF
它是一个常规字段,所以我们附加扩展名和一个 space,否则i
等于NF
,我们只想用换行符终止输出行。
它并不完美,它在最后一个文件名后附加了一个 space。我希望这足够好...
▶ A D D E N D U M ◀
我想联系:
- 最后的小号space...
- 一些the issues reported by Ed Morton
- 推广提供给
awk
的扩展
为了实现这些目标,我决定将 scriptlet 包装在一个 shell 函数中,将 spaces 更改为下划线的命名为 s2u
$ s2u () { awk -F'\.'' *' -v ext="." '{
> NF--;for(i=1;i<=NF;i++){gsub(" ","_",$i);printf "%s",$i ext (i<NF?" ":"\n")}}'
> }
$ echo "File Name1.xml File Name3 report.xml" | s2u xml
File_Name1.xml File_Name3_report.xml
$
有点不同(更好?)'cs 它不特别打印最后一个字段,而是 special-cases 附加到每个字段的分隔符,但拆分扩展名的想法仍然存在。
假设您问的是如何重命名文件名,而不是删除因其他原因而使用的文件名列表中的空格,这是长而短的方法。漫长的道路使用 sed。简短的方法使用重命名。如果您不是要重命名文件,则您的问题很不清楚,应该修改。
如果目标是简单地获取 xml 文件名列表并使用 sed 更改它们,下面的示例是如何做到这一点。
目录内容:
ls -w 2
bob is over there.xml
fred is here.xml
greg is there.xml
cd [directory with files]
shopt -s nullglob
a_glob=(*.xml);
for ((i=0;i< ${#a_glob[@]}; i++));do
echo "${a_glob[i]}";
done
shopt -u nullglob
# output
bob is over there.xml
fred is here.xml
greg is there.xml
# then rename them
cd [directory with files]
shopt -s nullglob
a_glob=(*.xml);
for ((i=0;i< ${#a_glob[@]}; i++));do
# I prefer 'rename' for such things
# rename 's/[[:space:]]/_/g' "${a_glob[i]}";
# but sed works, can't see any reason to use it for this purpose though
mv "${a_glob[i]}" $(sed 's/[[:space:]]/_/g' <<< "${a_glob[i]}");
done
shopt -u nullglob
结果:
ls -w 2
bob_is_over_there.xml
fred_is_here.xml
greg_is_there.xml
globbing 是你想要的,因为名称中有空格。
然而,这确实是一个复杂的解决方案,实际上您需要做的只是:
cd [your space containing directory]
rename 's/[[:space:]]/_/g' *.xml
就这样,大功告成。
另一方面,如果您正在尝试创建一个文件名列表,您肯定需要通配方法,如果您只修改语句,它也会执行您想要的操作,也就是说,只是使用 sed 更改输出文件名。
如果您的目标是为了输出而更改文件名,而不是重命名实际文件:
cd [directory with files]
shopt -s nullglob
a_glob=(*.xml);
for ((i=0;i< ${#a_glob[@]}; i++));do
echo "${a_glob[i]}" | sed 's/[[:space:]]/_/g';
done
shopt -u nullglob
# output:
bob_is_over_there.xml
fred_is_here.xml
greg_is_there.xml