解析Unix命令

时间:2014-05-26 10:44:29

标签: bash parsing unix

我希望解析命令ll *.dat > output.txt的返回。这产生了一个文本文件:

-rw-rw-rw-    1 root     root           16 Apr  8 12:15 01_entries.dat
-rw-rw-rw-    1 root     root           32 Apr 23 15:21 02_entries.dat

然后我要解析这些,所以我看到9个令牌对线:

permissionsnum of links valueusergroupsizemonthdaytimefilename

input1="output.txt"
while
        IFS='   ' read -r f1 f2 f3 f4 f5 f6 f7 f8 f9
do
        echo "$f1, $f2, $f3, $f4, $f5, $f6, $f7, $f8, $f9"
done < "$input1"

但这会锁定一个永恒的循环 - 有关如何让每一行正确解析的任何建议吗?

2 个答案:

答案 0 :(得分:3)

不是解析ls -l的输出(这非常容易出错,依赖于语言环境和所有),为什么不find直接为您提供所需输出的命令?

(是的,我知道。对不起的双关语抱歉。)

# -maxdepth 1: Maximum recursion depth (1 == current directory only).
# -type f: Files only (no directories).
# -name ...: Name pattern of files to list. Escape the \* so the shell does not.
# -printf ...: Format of the listing, printf() style:
#    %M: File permissions, symbolic view. Use %m for octal.
#    %n: Number of hard links to file.
#    %u: User name if present, or numeric ID. Use %U for numeric ID only.
#    %g: Group name if present, or numeric ID. Use %G for numeric ID only.
#    %s: File size in bytes. Use %b for 512-byte blocks, %k for 1k blocks.
#    %Tm: Last modification timestamp, month (01..12).
#    %Td: Last modification timestamp, day (01..31).
#    %TH: Last modification timestamp, hour (00..23). (Yanks use %TI and %Tp.)
#    %TM: Last modification timestamp, minute (00..59).
#    %p: Filename.
find . -maxdepth 1 -type f -name \*.dat -printf "%M,%n,%u,%g,%s,%Tm,%Td,%TH:%TM,%p\n"

检查man find以获取-printffind的更多选项。 (特别注意日期/时间字段,因为你不是在这里查询这一年......)


免费时间数据测验问题:%Ts的值范围是什么(修改时间,秒)?

  • 00..59?错。
  • 00..60?错。
  • 00..61?正确的。

如果您不知道原因,请更好地阅读&#34; leap seconds&#34;如果你想编写稳定的时间戳解析代码。 ; - )

答案 1 :(得分:2)

听起来你正试图制作某种类型的CSV文件。

可能更好地以正确的方式做到这一点(例如,Python有great library用于此目的)有多种原因:引用,文件名中的逗号,文件名中的空格,重要的空白等。

然而,bash中的快速解决方案可能是:

ls -l *.dat | awk '{print $1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9}'

你当然可以正确地迭代awk中的参数,但是,错误,它不是那么快又脏......

另请注意,这不会在您的脚本中使用别名ll - 它可能对不同的用户意味着不同的东西。最好直接使用二进制文件(ls -l)。