sed / awk - 删除文件名

时间:2017-08-19 18:32:45

标签: regex sed filenames

我正在尝试删除文件名中的空格并替换它们。

输入:

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

4 个答案:

答案 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的◀

我想解决:

为了实现这些目标,我决定将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脚本运行。

Demo

答案 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