我有一个文件夹,其中包含以下行的文件:
S149.sh
sox preaching.wav _001 trim 889.11 891.23
sox preaching.wav _002 trim 891.45 893.92
sox preaching.wav _003 trim 1599.95 1606.78
我希望在每行第一次出现S149
字符之前添加没有扩展名的文件名(_
),这样它最终看起来像这样:
sox preaching.wav S149_001 trim 889.11 891.23
sox preaching.wav S149_002 trim 891.45 893.92
sox preaching.wav S149_003 trim 1599.95 1606.78
我想自动为给定文件夹中的每个* .sh文件执行此操作。
如何使用bash(包括awk,grep,sed等)或python实现这一点?任何帮助将不胜感激。
答案 0 :(得分:2)
一种可能性,使用ed
,标准编辑器和循环:
for i in *.sh; do
printf '%s\n' ",g/_/ s/_/${i%.sh}&/" w q | ed -s -- "$i"
done
参数展开${i%.sh}
扩展为$i
,其中后缀.sh
已被删除。
ed
命令是i=S149.sh
:
,g/_/ s/_/S149&/
w
,g/_/
标记包含下划线的所有行,s/_/S149&/
用S149_
替换下划线。然后w
写入文件。
答案 1 :(得分:1)
sed
版本:
for i in *.sh; do
sed -i "s/_/${i%.*}_/g" "$i"
done
${i%.*}
扩展为文件名减去就地替换操作使用的扩展名。
答案 2 :(得分:1)
@ Ruran-如果您没有可以在读取Input_file时进行Input_file编辑的awk,那么以下内容可能对您有帮助。
awk '(FILENAME != P && P && Q){close(P);system("mv " Q OFS P)} {Q=P=FILENAME;sub(/\..*/,X,Q);sub(/_/,Q"&");print > Q;} END{system("mv " Q OFS P)}' *.sh
逻辑,后面很简单,它正在改变_(char)的第一次出现,然后它将新的格式化行保留到tmp文件中,同时读取下一个Input_file,它将该临时文件重命名为先前的Input_file。
还有一点,我在上面没有看到它,因为我们正在使用* .sh所以让我们说你有成千上万的Input_files然后代码可能会给出错误,因为会打开太多的Input_files而且我们是不关闭文件,所以我也关闭它们,让我知道这是否有助于你。
非单一衬里形式的解决方案也如下。
awk '(FILENAME != P && P && Q){
close(P);
system("mv " Q OFS P)
}
{
Q=P=FILENAME;
sub(/\..*/,X,Q);
sub(/_/,Q"&");
print > Q;
}
END {
system("mv " Q OFS P)
}
' *.sh
答案 3 :(得分:0)
使用GNU awk进行就地编辑:
awk -i inplace 'FNR==1{f=gensub(/\.[^.]+$/,"",1,FILENAME)} {$3=f$3} 1' *.sh
如果您正在考虑使用shell循环,请参阅why-is-using-a-shell-loop-to-process-text-considered-bad-practice。