Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.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
Bash-添加0';在文件名中间_Bash_Shell - Fatal编程技术网

Bash-添加0';在文件名中间

Bash-添加0';在文件名中间,bash,shell,Bash,Shell,我有一堆文件,它们的名字是: mem0.csv mem1.csv . . . . mem153.csv . . . 它们都在同一个文件夹中。当我在文件夹中进行ls时,它们按顺序显示 mem0.csv mem1.csv mem10.csv mem100.csv . . . mem2.csv mem20.csv . . . 我想创建一个bash脚本,在mem和数字之间推送0。我想我需要添加0,直到所有文件名都具有相同的长度。唯一的问题是我不知道如何执行此操作。您可以使用printf工具,只要

我有一堆文件,它们的名字是:

mem0.csv
mem1.csv
.
.
.
.
mem153.csv
.
.
.

它们都在同一个文件夹中。当我在文件夹中进行ls时,它们按顺序显示

mem0.csv
mem1.csv
mem10.csv
mem100.csv
.
.
.
mem2.csv
mem20.csv
.
.
.


我想创建一个bash脚本,在mem和数字之间推送0。我想我需要添加0,直到所有文件名都具有相同的长度。唯一的问题是我不知道如何执行此操作。

您可以使用printf工具,只要确保您的系统拥有它(几乎所有现代系统都有它) 要将它们全部重命名,请执行以下操作:

for i in {1..153}; do
    mv mem$i.csv mem`printf "%03d" $i`.csv
done
编辑: 对于随机数目的文件,代码将如下所示:

dir = "/somedir"
fn = $(ls -l $dir | wc -l)
z = 0;
c = $fn
# Count the number of zero's to use
while [ $c -gt 0 ]; do
    (( $z++ ))
    c = $(( $c / 10 ))
done
# Rename the files
while [ $fn -gt 0 ]; do
    mv ${dir}/mem$fn.csv ${dir}/mem$(printf "%0${z}d" $i).csv
    (( $fn-- ))
done

GNU coreutils提供的
ls
支持:

$ls-v mem0.csv mem1.csv mem2.csv ... mem10.csv ...
嗯。我是这样做的。我知道这不是正确的方法,但通过这种方式,我有机会理解一些东西

#Cleaning the dest folder
cd "out"
rm *
cd ".."

#setting some variables
MAXLEN=-1

#Searching for the longest file name
for f in mem*.csv; do
   LEN=${#f}
   if [  $MAXLEN -lt $LEN  ]; then
      let MAXLEN=$LEN
   fi
done

for f in mem*.csv; do
   LEN=${#f}
   let LEN+=1
   COUNT="0" 
   until [ $MAXLEN  -lt $LEN  ]; do #Creating 0's string to add
      COUNT=$COUNT"0"
      let LEN+=1
   done
      CLEN=${#COUNT} #The string has one 0 more than it should have. We take that into an account
      let CLEN-=1
      echo $CLEN
      if [  $CLEN != 0  ]; then
         COUNT=${COUNT:0:$CLEN} #The string is to long, remove the last 0
         number=$(echo $f | tr -cd '[[:digit:]]') #Extracting the number from the rest of the file name
         cp $f "out/mem"$COUNT$number".csv" #creating the new file

 else
         cp $f "out/"$f
      fi
done


ls "out/"
我认为ls-v(正如@ephemient所指出的)可以满足您的需要,但是如果您真的必须用零填充数字,那么根据提供的文件名模式,这里有一种快速而肮脏的方法

last=$(ls -v *.csv | tail -n1) # last file has the biggest number
let max=${#last}-7 # minus the number of all the other chars (constant)

# below grep gets only the number part and head ignores the last line
# which we don't need to change 
ls -v mem*.csv | egrep -o '[0-9]+' | head -n -1 | \
while read n; do
    mv -ivf mem$n.csv mem$(printf "%0"$max"d" $n).csv
done

bash脚本有什么特别的原因吗?+1但我建议使用
mv mem$i.csv mem$(printf“%03d”$i)。csv
,因为反勾号不是POSIX,已被弃用。问题是我不知道文件夹中有多少文件。这意味着我不知道需要输入多少个0。在这种情况下,首先计算文件的数量,并将零的数量输入变量(例如$z)。然后您可以将其传递给命令。@dtech,您最近用Perl编程过吗
$z=0
不是shell语法:您显然想要
z=0
,也不需要
ls-l
(减去ell):当在管道中调用ls时,它的行为类似于
ls-1
(减去1)
last=$(ls -v *.csv | tail -n1) # last file has the biggest number
let max=${#last}-7 # minus the number of all the other chars (constant)

# below grep gets only the number part and head ignores the last line
# which we don't need to change 
ls -v mem*.csv | egrep -o '[0-9]+' | head -n -1 | \
while read n; do
    mv -ivf mem$n.csv mem$(printf "%0"$max"d" $n).csv
done