我是新手...我需要一个脚本,它接收一个目录作为参数并打印出 15 到 50 行之间的文件的名称,但我不知道如何wc
在if
句子中使用输出:
#!/bin/bash
for f in `ls`; do
echo "File -> $f"
cat $f | wc -l
done
我如何接收参数?如何将输出分配wc
给变量?
答案1
参数可以作为$1
、$2
等来接收,或者$*
全部接收。
还有数组$@
,通常用作"$@"
的更好版本$*
。另一种可能的用法是${@:3}
表示“从第 3 个开始的所有参数”。
要获取命令的输出,请使用$( ... )
或其旧形式` ... `
。通常建议总是使用,$()
因为它可以嵌套,例如blah=$(cat /blah/$(blah)/blah)
。
#!/usr/bin/env bash
for dir in "$@"; do
for file in "$dir"/*; do
lines=$(wc -l < "$file")
if (( lines >= 15 && lines <= 50 )); then
echo "File -> $file ($lines lines)"
fi
# another possible syntax:
# if [ "$lines" -ge 15 ] && [ "$lines" -le 50 ]
# or:
# if [[ "$lines" -ge 15 && "$lines" -le 50 ]]
done
done
有用的资源:
答案2
下面是另一种使用方法awk
:
#!/usr/bin/env bash
for dir in "$@"; do
for file in "$dir"/*; do
awk 'END{if(NR>=15 && NR<=50){print FILENAME}}' "$file";
done
done
说明:(awk
及其许多变体,如gawk
或mawk
等)逐行读取文件。变量NR
是当前行号。END{}
当到达输入文件的最后一行时,将执行一个块,此时NR
将是文件中的行数。最后,FILENAME
是当前正在处理的文件的名称。因此,如果脚本看到的行数在 15 到 50 之间,它将打印文件的名称。
类似地,你可以用 Perl 来做到这一点:
#!/usr/bin/env bash
for dir in "$@"; do
for file in "$dir"/*; do
perl -ne 'END{if($. >=15 && $. <=50){print "$ARGV\n"}}' "$file"
done
done
说明:perl -ne
还将逐行读取文件。在 Perl 中,当前行号存储在中$.
,END
块的工作方式与 中相同awk
。$ARGV
是在命令行上传递的参数,文件名只有在行数正确时才会打印。
你最好的选择可能是 bash 和wc
回答@grawity 但这些不会受到wc
实现的影响并且应该可以在任何 *nix 上很好地运行。
答案3
生成一些文件:
$ for i in `seq -w 1 60`; do seq -w 1 $i > $i.lines; done
仅打印符合条件的:
$ wc -l * | awk '$1 >= 15 && $1 <= 50 { print $2 }' | column
15.lines 23.lines 31.lines 39.lines 47.lines
16.lines 24.lines 32.lines 40.lines 48.lines
17.lines 25.lines 33.lines 41.lines 49.lines
18.lines 26.lines 34.lines 42.lines 50.lines
19.lines 27.lines 35.lines 43.lines
20.lines 28.lines 36.lines 44.lines
21.lines 29.lines 37.lines 45.lines
22.lines 30.lines 38.lines 46.lines