繁体   English   中英

如何在bash中将`ls -l`的输出解析为多个变量?

[英]How to parse the output of `ls -l` into multiple variables in bash?

关于此主题已经有一些答案,但是几乎所有人都说解析ls -l的输出很不好,因此建议使用其他方法。

但是,我使用的是ncftpls -l ,所以不能使用诸如shell globs之类的东西或find –我认为我真正需要解析ls -l输出。 如果您对ncftpls不熟悉,请不要担心,输出将返回与您仅使用ls -l完全相同的格式。

在公共远程ftp目录中有文件列表,我不想每次cronjob触发时都重新下载每个所需的文件,从而给远程服务器增加了负担。 我要检查ftp目录中文件子集的每个子集,文件是否在本地; 如果没有,请下载。

这很简单,我只是使用

tdy=`date -u '+%Y%m%d'`_

# Today's files
for i in $(ncftpls 'ftp://theftpserver/path/to/files' | grep ${tdy}); do
    if [ ! -f $i ]; then
        ncftpget "ftp://theftpserver/path/to/files/${i}"
    fi
done

但是我遇到了一个问题,有时cron作业会下载尚未完成上传的文件,因此,当下次启动时,它会跳过部分下载的文件。

因此,我想添加一个检查以确保对于我已经拥有的每个文件,本地文件大小与远程服务器上相同文件的大小匹配。

我一直在考虑解析ncftpls -l的输出并使用awk,类似于

for i in $(ncftpls -l 'ftp://theftpserver/path/to/files' | awk '{print $9, $5}'); do
    ...
    x=filesize   # somehow get the file size and the filename
    y=filename   # from $i on each iteration and store in variables
    ...
done

但是我似乎无法在循环的同一迭代中将服务器的文件名和文件大小都转换为局部变量。 每次迭代时,$ i在awk字符串中的$ 9和$ 5之间交替。

如果我每次迭代都能获取文件名并将其文件化为单独的变量,则可以简单地使用stat -c "%s" $i获取本地大小并将其与远程大小进行比较。 然后在我还没有的每个远程文件上添加一个简单的ncftpget 我也修改了lftp类的同步程序,但是运气不太好,宁愿这样。

任何帮助表示赞赏!

当看到任何空格(例如空格,制表符或换行符)时,for循环将拆分。 因此,在循环之前需要IFS((关于...有很多问题)

IFS=$'\n' && for i in $(ncftpls -l 'ftp://theftpserver/path/to/files' | awk '{print $9, $5}'); do

echo $i | awk '{print $NF}' # filesize 
echo $i | awk '{NF--; print}' # filename
# you may have spaces in filenames, so is better to use last column for awk

done

我认为更好的方法是不使用而使用

ls -l | while read i
do
echo $i | awk '{print $9, $5}'

#split them if you want 
x=echo $i | awk '{print $5}'
y=echo $i | awk '{print $9}'

done

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM