我正在尝试删除文件名中的空格并替换它们。
输入:
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
答案 0 :(得分:1)
您在问题标题中命名为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或更多空格{for(i=1;i<=NF;i++)
- 注意最后一个字段是无效的(它是在最后一个扩展名之后),但我们是要考虑到这一点... gsub(" ","_", $i)
将所有出现的空格替换为当前字段中的下划线,由循环变量i
printf i<NF?$i ".xml ":"\n"
输出不同的内容,如果i<NF
它是常规字段,那么我们会附加扩展名和空格,否则i
等于NF
,我们只是想要用换行符终止输出行。它并不完美,它会在最后一个文件名后附加一个空格。我希望这足够好......
▶甲d d简d U m的◀
我想解决:
awk
为了实现这些目标,我决定将scriptlet包装在shell函数中,将空格更改为下划线的名称为s2u
$ s2u () { awk -F'\.'$1' *' -v ext=".$1" '{
> 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 cs它没有特殊打印最后一个字段,而是特殊情况下附加到每个字段的分隔符,但分裂扩展的想法仍然存在。< / p>
答案 1 :(得分:0)
如果文件名没有被描述,这似乎是一个好的开始:
((?:\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脚本运行。
答案 2 :(得分:0)
假设您正在询问如何重命名文件名,而不是删除由于某些其他原因而使用的文件名列表中的空格,这是多方面的。漫长的方式使用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
就是这样,你已经完成了。
另一方面,如果你试图创建一个文件名列表,你肯定想要一个globbing方法,如果你只是修改语句,那么你也可以做你想要的,也就是说,只使用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
答案 3 :(得分:-1)
您可以使用rename
:
rename --nows *.xml
这将使用_
替换当前文件夹中xml文件的所有空格。
有时它没有--nows
选项,因此您可以使用搜索并替换:
rename 's/[[:space:]]/__/g' *.xml
如果您只想打印文件名而不编辑名称,最终可以使用--dry-run
。