Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何将数字连续的文件名更改为相同的前缀但不同的后缀名?_Linux_Sed_Awk - Fatal编程技术网

Linux 如何将数字连续的文件名更改为相同的前缀但不同的后缀名?

Linux 如何将数字连续的文件名更改为相同的前缀但不同的后缀名?,linux,sed,awk,Linux,Sed,Awk,假设我有4000个文件: output1 output2 output3 output4 output5 output6 output7 output8 ..... output3999 output4000 如何更改前缀相同但后缀不同的每两个数字连续文件?在本例中,我希望将文件名更改为: output1 -> Type0001_A.abc output2 -> Type0001_B.abc output3 -> Type0002_

假设我有4000个文件:

output1
output2
output3
output4
output5
output6
output7
output8 
.....
output3999
output4000
如何更改前缀相同但后缀不同的每两个数字连续文件?在本例中,我希望将文件名更改为:

output1        -> Type0001_A.abc
output2        -> Type0001_B.abc
output3        -> Type0002_A.abc
output4        -> Type0002_B.abc
output5        -> Type0003_A.abc
output6        -> Type0003_B.abc
output7        -> Type0004_A.abc
output8        -> Type0004_B.abc
.....             .....
output3999     -> Type2000_A.abc
output4000     -> Type2000_B.abc
我已经做了一个简单的循环,可以解决前缀,但不知道如何后缀数字和字母可以做到

for i in `find . -name "output*"`
do
l=`echo $i |sed 's/output/Type/'`
'$i > $l`
done
有什么建议吗?关于“循环”的更多在线参考非常感谢。谢谢。

你可以写:

for suffix in 000{1..9} 00{10..99} 0{100..999} {1000..2000} ; do
    mv "output$((10#$suffix * 2 - 1))" "Type${suffix}_A.abc"
    mv "output$((10#$suffix * 2))" "Type${suffix}_B.abc"
done
注:

  • 这里不需要双引号,但如果没有双引号,堆栈溢出语法highlighter会变得非常混乱。(特别是,它认为以十为基数的算术常数中的
    #
    开始了注释。)而且,无论如何,用双引号将参数展开式括起来总是一种好的做法
  • 如果您愿意,您可以使用外部程序
    seq
    ,编写
    $(seq-w 1 2000)
    来简化第一行,而不是
    000{1..9}00{10..99}0{100..999}{1000..2000}
    。因此,如果您有bash4.x,您可以只编写
    {0001..2000}
这可能适合您(GNU-sed¶llel):

对于bash:

i=0
ab=( [0]=A [1]=B )
for f in output*; do 
    n=${f#output}
    printf -v newname "Type%04d_%c.abc\n" $(( (n+1)/2 )) ${ab[i]}
    i=$(( (i+1)%2 ))
    mv "$f" "$newname"
done
你可以做:

seq 1 2000 | while read num; do
  echo "output$((num*2-1))" "Type$(printf "%04d" $num)_A.abc"
  echo "output$((num*2+0))" "Type$(printf "%04d" $num)_B.abc"
done
如果您对输出满意,请通过
mv
更改
echo


可以在shell的man中找到有关循环的引用。

另一个使用awk的解决方案:

awk '{if(NR%2){printf "%s%s%04d%s\n",$0, " -> Type",(NR+1)/2,"_A.abc"} else {printf "%s%s%04d%s\n",$0, " -> Type",NR/2,"_B.abc" }}' file

使用GNU Parallel,您可以执行以下操作:

parallel mv output{#} Type{1}_{2}.abc ::: {0001..2000} ::: A B

您可以在增加2的for循环中轻松地执行此操作,但这不允许进行任何健全性检查。我建议使用您选择的脚本语言生成一系列
mv
命令,您可以在将它们送入shell之前对其进行目视检查。应该是一个循环和一些简单的算术/字符串操作。非常好。你能澄清一下
10
的作用吗?这仅仅是子字符串的删除吗?@N13:在一个算术表达式中,
7#32
形式的常数意味着“以
7
为基数表示为
32
(即3×7+2=23)的整数”。通常
10#
是不必要的,但是以
0
开头的常数取基数8,例如,
032
表示3×8+2=26,
$suffix
被零填充到四位,所以我使用前缀
10#
来防止这种情况。
parallel mv output{#} Type{1}_{2}.abc ::: {0001..2000} ::: A B