Bash:仅抓取第二行和最后一行输出(ls -lrS)

时间:2015-11-30 16:34:07

标签: bash shell awk ls

我希望获得ls -lrS命令输出的第二行和最后一行。我一直在使用ls -lrS | (head -2 | tail -1) && (tail -n1)但它似乎只得到第一行,我必须按控制C来阻止它。

我遇到的另一个问题是使用awk命令,我只想抓取文件大小和文件名。如果我要获得正确的行(第二行和最后一行),我想要的输出将是

files=$(ls -lrS | (head -2 | tail -1) && (tail -n1) awk '{ print "%s", $5; "%s", $8; }' )

我希望它会打印出来:

1234 file.abc

12345 file2.abc

4 个答案:

答案 0 :(得分:5)

使用格式稳定的GNU stat命令:

stat --format='%s %n' * | sort -n | sed -n '1p;$p'

如果您使用的是BSD stat,请进行相应调整。

如果您想要更多地控制哪些文件进入此计算,并且可以说更好的可移植性,请使用find。在这个例子中,我得到当前目录中的所有非点文件:

find -maxdepth 1 -not -path '*/\.*' -printf '%s %p\n' | sort -n | sed -n '1p;$p'

如果您的目录包含两个或更少的条目,或者您的任何条目的名称中都有换行符,请注意。

答案 1 :(得分:2)

使用awk

ls -lrS | awk 'NR==2 { print; } END { print; }'

当行号print为2且最后一行时,NR$0

注意:正如评论中所指出的,END阻止awk块可能会或可能不会提供<form> <input id="uploader1" type="file" accept="image/*" style="display:none;" required> <label for="uploader1"> <div class="square" id="myImg1"></div> </label> ,具体取决于您的.square{ position: relative; width: 50%; cursor: pointer; } .square:before{ padding-top: 95%; display:block; content: ""; } #myImg1 { background: url('button.jpg') no-repeat center; background-size: cover; } #myImg1:hover {background:url('buttonHover.jpg') no-repeat center; background-size: cover; } #myImg1:active { background:url('buttonClick.jpg') no-repeat center; background-size: cover; } #uploader1 > input { display:none; } 版本。

答案 2 :(得分:1)

ls不是这项工作的可靠工具:它不能代表所有可能的文件名(空格是可能的,还有换行符和其他特殊字符 - 除了NUL之外)。使用GNU工具的系统的一个强大解决方案是使用find

{
    # read the first size and name
    IFS= read -r -d' ' first_size; IFS= read -r -d '' first_name;

    # handle case where only one file exists
    last_size=$first_size; last_name=$first_name

    # continue reading "last" size and name, until one really is last
    while IFS= read -r -d' ' curr_size && IFS= read -r -d '' curr_name; do
      last_size=$curr_size; last_name=$curr_name
    done
} < <(find . -mindepth 1 -maxdepth 1 -type f -printf '%s %P\0' | sort -n -z)

上述内容将结果放入变量$first_size$first_name$last_size$last_name,因此可以使用:

printf 'Smallest file is %d bytes, named %q\n' "$first_size" "$first_name"
printf 'Largest file is %d bytes, named %q\n' "$last_size" "$last_name"

就其运作方式而言:

find ... -printf '%s %P\0'

...从find发出以下表单的流:

<size> <name><NUL>

通过sort -n -z运行该流对其内容进行数字排序。 IFS= read -r -d' ' first_size读取第一个空间的所有内容; IFS= read -r -d '' first_name读取第一个NUL的所有内容;然后循环继续读取并存储其他大小/名称对,直到到达最后一个。

答案 3 :(得分:1)

whatever | awk 'NR==2{x=$0;next} {y=$0} END{if (x!="") print x; if (y!="") print y}'

你需要这种复杂性(以及更多的非常强大)来处理少于3行的输入。