Felix Dombek Asked: 2019-08-22 06:08:35 +0800 CST2019-08-22 06:08:35 +0800 CST 2019-08-22 06:08:35 +0800 CST 如何查看文件夹文件中的第 17 行(或最后一行,如果更少)? 772 我目前正在使用 watch head -n 17 * 这有效,但也显示所有行到第 17 行。基本上,我只想显示以我当前的方法显示的每个文件的最后一行。我怎样才能做到这一点? 例子 为了举例,让我们减少行 nr。到 7. 所以: 示例文件: 1 2 3 4 5 6 7 8 这一行: watch head -n 7 * 输出 1 2 3 4 5 6 7 我想要的地方: 7 bash head 3 个回答 Voted Best Answer Stéphane Chazelas 2019-08-22T06:29:43+08:002019-08-22T06:29:43+08:00 使用 GNU awk: watch -x gawk ' FNR == 17 {nextfile} ENDFILE {if (FNR) printf "%15s[%02d] %s\n", FILENAME, FNR, $0}' ./* 这给出了如下输出: ./file1[17] line17 ./short-file2[05] line 5 is the last 请注意, glob 仅在调用./*时展开一次。watch 你watch head -n 17 *是一个任意命令注入漏洞,因为它的扩展*实际上被 shell 解释为 shell 代码,watch调用来解释其参数与空格的连接。 如果$(reboot)当前目录中有一个文件被调用,它将重新启动。 使用-x,我们告诉watch您跳过 shell 并直接执行命令。或者,您可以这样做: watch 'exec gawk '\'' FNR == 17 {nextfile} ENDFILE {if (FNR) printf "%15s[%02d] %s\n", FILENAME, FNR, $0}'\'' ./*' 为了watch运行一个外壳,它将./*在每次迭代时扩展该 glob。watch foo bar实际上与 相同watch -x sh -c 'foo bar'。使用时watch -x,您可以指定所需的 shell,例如选择一个更强大的 shell,zsh这样可以进行递归通配并限制为常规文件: watch -x zsh -c 'awk '\''...'\'' ./**/*(.)' 没有gawk,您仍然可以执行以下操作: watch ' for file in ./*; do [ -s "$file" ] || continue printf "%s: " "$file" head -n 17 < "$file" | tail -n 1 done' 给出如下输出: ./file1: line17 ./short-file2: line 5 is the last 但这会降低效率,因为它意味着每个文件运行多个命令。 hyde 2019-08-22T21:35:06+08:002019-08-22T21:35:06+08:00 在这两个示例中组合head并喜欢:tail $ seq 1 80 | head -n 17 | tail -n 1 17 $ seq 1 10 | head -n 17 | tail -n 1 10 所以要解决你的实际问题,命令是: watch 'for f in *; do head -n 17 -- "$f" 2>/dev/null | tail -n 1 ; done' 请注意该2>/dev/null部分,它是必需的,因为 * 将匹配目录和您可能无权读取的任何文件,这将产生错误消息,您可能想要隐藏它。 dhanlin 2019-08-22T09:06:40+08:002019-08-22T09:06:40+08:00 find、exec 和 sed 的另一种方法 watch find . -type f -name \"*\" -exec sh -c \'\( printf '%-50s ' {} \; sed -n 17p {}\)\' \\\;
使用 GNU
awk
:这给出了如下输出:
请注意, glob 仅在调用
./*
时展开一次。watch
你
watch head -n 17 *
是一个任意命令注入漏洞,因为它的扩展*
实际上被 shell 解释为 shell 代码,watch
调用来解释其参数与空格的连接。如果
$(reboot)
当前目录中有一个文件被调用,它将重新启动。使用
-x
,我们告诉watch
您跳过 shell 并直接执行命令。或者,您可以这样做:为了
watch
运行一个外壳,它将./*
在每次迭代时扩展该 glob。watch foo bar
实际上与 相同watch -x sh -c 'foo bar'
。使用时watch -x
,您可以指定所需的 shell,例如选择一个更强大的 shell,zsh
这样可以进行递归通配并限制为常规文件:没有
gawk
,您仍然可以执行以下操作:给出如下输出:
但这会降低效率,因为它意味着每个文件运行多个命令。
在这两个示例中组合
head
并喜欢:tail
所以要解决你的实际问题,命令是:
请注意该
2>/dev/null
部分,它是必需的,因为 * 将匹配目录和您可能无权读取的任何文件,这将产生错误消息,您可能想要隐藏它。find、exec 和 sed 的另一种方法