在Bash Shell中用for循环与sed提取ls -l结果的日期及文件名
提取SFTP ls结果中的日期与文件名
嘿,先给你提个小问题:你现在的for循环写法有点坑——ListOfFiles=$(sed '1,2d' $LstFile)会把文件里原本每行一个的ls条目,变成一堆用空格堆起来的长字符串,直接用for line in $ListOfFiles循环的话,会把权限、数字、日期片段这些单个字段都当成循环项,完全不是你要的每个文件的完整条目啊!
先把循环逻辑改对,推荐用while read逐行读取处理后的文件内容,这样每个循环的line就是一个完整的文件ls记录:
# 直接处理删除前两行后的文件,逐行读取 while read -r line; do # 用sed提取我们要的日期和文件名 target_content=$(echo "$line" | sed -E 's/^([^ ]+ +){5}//') echo "$target_content" done < <(sed '1,2d' "$LstFile")
给你拆解一下这个sed命令sed -E 's/^([^ ]+ +){5}//':
-E:启用扩展正则表达式,这样写括号和重复次数的时候不用额外加转义符,更顺手^([^ ]+ +){5}:专门匹配行开头的5个无用字段:[^ ]+:匹配一段不含空格的字符(对应ls里的权限、链接数这类单个字段)+:保证这段字符至少有一个长度{5}:把这个匹配规则重复5次,刚好覆盖权限、链接数、所有者、组、文件大小这5个我们不需要的部分
//:把匹配到的这些无用内容替换成空,剩下的自然就是日期(月、日、时间)和zip文件名啦
要是你非得坚持用原来的变量存储方式(其实不太推荐,长字符串处理容易出问题),也可以先把变量里的换行恢复回来再处理:
ListOfFiles=$(sed '1,2d' "$LstFile") # 把变量里的内容按原换行拆分,逐行处理 echo "$ListOfFiles" | while read -r line; do target_content=$(echo "$line" | sed -E 's/^([^ ]+ +){5}//') echo "$target_content" done
另外,如果你想直接把所有结果拼成一行(就像你示例里的Dec 6 11:58 1.zip Dec 6 11:59 10.zip),甚至不用循环,直接用sed加tr命令一步搞定:
# 先删前两行,再每行提取目标内容,最后把所有行换成空格连起来 sed '1,2d; s/^([^ ]+ +){5}//' "$LstFile" | tr '\n' ' ' # 最后加个echo自动换行,看起来更舒服 sed '1,2d; s/^([^ ]+ +){5}//' "$LstFile" | tr '\n' ' ' && echo
这样就能一次性得到你想要的结果咯!
内容的提问来源于stack exchange,提问作者Dridj
相关产品推荐
相关产品推荐

