将单个输出行保存到变量中

chu*_*nky 3 shell bash output

我正在使用find -mtime -2查找在过去 24 小时或更短时间内修改过的文件。输出看起来像这样。

/home/user/logs/file-2014-08-22.log
/home/user/logs/file-2014-08-23.log
Run Code Online (Sandbox Code Playgroud)

我需要将输出的第一行保存到一个变量中,然后将第二行保存到一个单独的变量中。我不能只是管它。我知道您可能会建议,| grep 22或者23这是将运行多次的 bash 脚本的一部分,下次会有一组不同名称的不同文件,所以grep太具体了。能awk做到这一点吗?如果是这样,如何?.

Mic*_*mer 8

假设您的任何文件名中都没有空格等,有几种方法可以做到这一点。一种是使用数组:

files=( $(find -mtime -2) )
a=${files[1]}
b=${files[2]}
Run Code Online (Sandbox Code Playgroud)

files将是按find顺序输出的所有路径的数组,从零开始索引。你可以从中得到任何你想要的线条。在这里,我将第二行和第三行保存到aand 中b,但您也可以直接使用数组元素。

如果您有 GNU find 或其他printf选项,则另一种选择是将它read进程替换结合使用:

read junk a b junk < <(find -printf '%p ')
Run Code Online (Sandbox Code Playgroud)

这将所有find的输出转换为一行,然后将该行作为输入提供给read,这会将第一个单词(路径)保存到junk,第二个到 中a,第三个到 中b,并将该行的其余部分junk再次保存到。

同样,您可以在任何 POSIX 兼容系统上引入相同效果的paste命令

read junk a b junk < <(find -mtime -2 | paste -s)
Run Code Online (Sandbox Code Playgroud)

paste -s将其输入转换为单个制表符分隔的行,read可以再次处理。

在一般情况下,如果您愿意多次执行主命令(此处不需要),您可以sed轻松使用:

find | sed -n 2p
Run Code Online (Sandbox Code Playgroud)

这将只打印输出的第二行,通过抑制普通输出-n并选择第 2 行进行p打印。您也可以拼接在一起head,并tail达到相同的效果,这可能会在很长的文件,更高效。

所有的上面有第二行和第三行存储到相同的效果ab,所有仍然有没有空格,制表符,换行符,或发生在你的任何其他字符的假设输入分隔符(IFS值在任何文件名中。


请注意,尽管 of 的输出顺序find未定义,因此“第二个文件”并不是真正有用的标识符,除非您将它们组织为以其他方式排序。在许多情况下,它可能接近创建顺序,但不是全部。


cuo*_*glm 5

使用bash 4.x,您可以使用mapfile

$ mapfile -t <<< "$(find -mtime -2)"
$ printf "%s\n" "${MAPFILE[0]}"
/home/user/logs/file-2014-08-22.log
$ printf "%s\n" "${MAPFILE[1]}"
/home/user/logs/file-2014-08-23.log
Run Code Online (Sandbox Code Playgroud)

mapfile从标准输入读取行到索引数组变量中,默认数组是MAPFILE. 您可以指定数组的名称:

mapfile -t array <<< "$(find -mtime -2)"
Run Code Online (Sandbox Code Playgroud)

-t选项导致mapfile从读取的每一行中删除尾随换行符。

  • @Bernhard:更新了答案。 (2认同)