在unix中使用for循环查找文件的大小

在unix中使用for循环查找文件的大小

我正在尝试使用 for 循环获取目录中每个文件的大小,运行以下脚本

#!/bin/bash
FILE=/home/cloudera/Desktop/new
for    file in $FILE
do
       size=`du -b ${file} | cut -f1`
       echo $size
done

我收到以下错误:

du cannot access /home/cloudera/Desktop/new/a.txt 
du cannot access /home/cloudera/Desktop/new/b.txt 
du cannot access /home/cloudera/Desktop/new/c.txt

其中 a.txt、b.txt.c.txt 是新目录中的文件。

答案1

du -b我可以建议您使用 find 和 printf来代替。这里的主要问题是 du 会递归到它找到的任何目录。您的for循环无法查看各个文件。

find /home/cloudera/Desktop/new -type f -printf "%s %p\n"

如果你的发现没有 printf,那么使用

-exec stat -c "%s %n" {} \;

然后将输出通过管道传输到 while 脚本:

find <what you do above> | 
while read size ; do 
   # whatever
done

编辑:您似乎想要查找 SOURCEDIR 中的每个文件,如果该文件不存在于 DESTDIR 中,或者该文件确实存在但文件大小不同,则复制该文件。

CP="echo /bin/cp -f"
sizeof() { stat -c %s "%1" ; }
cd $SOURCEDIR
find . -type f -print |
  while read name; do
    source_size=$(sizeof $SOURCEDIR/$name)
    if [[ -f $DESTDIR/$name ]]; then
      dest_size=$(sizeof $DESTDIR/$name)
      if [[ $source_size == $dest_size ]]; then
        next # do not copy
      fi
    fi
    $CP $SOURCEDIR/$name $DESTDIR/$name
  done

但这是丑陋且缓慢的。cd确保 find 的输出都是相对路径是必要的。随后使用$SOURCEDIR是多余的并且是为了清晰起见。我给 the 起了别名,sizeof以便您可以将其更改为du -b其他名称。当输出看起来正确时,更改$CP为真正的命令(remove echo)。

这是另一种方法来做到这一点。如果你学得好,你将掌握关于unix的很多东西:

CP="echo cp"
{ cd $SOURCEDIR ; find . -type f -printf "%s %p\n" |sort -k 2 ; } >/tmp/source.lst
{ cd $DESTDIR   ; find . -type f -printf "%s %p\n" |sort -k 2 ; } >/tmp/dest.lst
awk 'FNR==NR { f[$2]=$1 } !length(f[$2]) || f[$2]!=$1 { print $2 }' /tmp/dest.lst /tmp/source.lst >/tmp/copythese.lst
cat /tmp/copythese.lst | xargs -n 1 -I ^ $CP $SOURCEDIR/^ $DESTDIR/^ 

测试一下。然后,当列表看起来正确时,更改CP/bin/cp -f并重复上一个命令。您正在执行上述步骤,但使用列表。 awk 命令查找源中不在目标中或大小不同的文件。 ($1 是大小,$2 是文件名,$f[$2] 是文件的大小目的地)。然后为 中的每一行xargs运行一个 的实例。$CPcopythese.lst

答案2

#!/bin/bash
DIR=/home/cloudera/Desktop/new
for    file in $DIR/*
do
       wc -c "$file"
done

答案3

该脚本显示一个pair <SIZE> <FILE>,其中<SIZE>是它自己的大小(以字节为单位),<FILE>可以是文件或目录。如果您只想显示文件,则必须删除第一个条件并使用第二个条件。

#!/bin/bash
FILE=/home/cloudera/Desktop/new

for i in `ls $FILE`
do
    if [ -d "$FILE/$i" ]
    then
        msg=`ls -ld $FILE/$i`
        size=$(echo $msg | awk -F [\ ] '{print $5}')
        file=$(echo $msg | awk -F [\ ] '{print $9}')
        echo -e "$size \t  $file"

    elif [ -f "$FILE/$i" ]
    then
        msg=`ls -l $FILE/$i`
        size=$(echo $msg | awk -F [\ ] '{print $5}')
        file=$(echo $msg | awk -F [\ ] '{print $9}')
        echo -e "$size \t  $file"
    fi
done

相关内容