我创建了一个 shell 脚本,但我不知道如何执行一个循环来打印作为参数传递给脚本的每个文件中的行数。这样输出就会是这样的:
2 lines in hello.sh
33 lines in /var/log/syslog
答案1
假设是 POSIX shell,您需要for
在此处进行循环,循环"$@"
包含命令行参数:
for filename in "$@"; do
lines=$(wc -l < "$filename")
printf '%u lines in %s\n' "$lines" "$filename"
done
使用所有的引号非常重要。它允许您传递包含空格和其他字符的文件名。
./my_script.sh /var/log/syslog "$HOME/My Dir with Spaces/a file with spaces.txt"
答案2
一般来说,要循环脚本或 shell 函数中的命令行参数,您可以这样做
for thing do
commands using "$thing"
done
或者
for thing in "$@"; do
commands using "$thing"
done
在这种情况下,假设命令行上给出的文件名不包含文字换行符,则无需为此执行显式 shell 循环:
wc -l -- "$@" | sed -E '$d;s/^[[:blank:]]*([[:digit:]]*)[[:blank:]]*(.*)/\1 lines in \2/'
这将获取所有命令行参数并wc -l
对其全部运行。
解析输出,sed
丢弃包含给定文件中总行数的最后一行(使用$d
)。wc -l
通过捕获行数和文件名,然后lines in
在其间插入字符串,将输出的其余部分转换为您想要的输出。
用我自己的脚本运行脚本.vimrc
,.profile
文件.mailrc
将返回
8 lines in .vimrc
8 lines in .profile
4 lines in .mailrc
请注意,这wc -l -- "$@"
将创建类似的输出
8 .vimrc
8 .profile
4 .mailrc
20 total
这实际上可能足以满足您的需求,而不需要sed
.
答案3
#!/bin/bash
for file in "${@}"; do
wc -l -- "${file}"
done
#!/bin/bash
将执行该脚本的程序。
${@}
立场论据。您通过命令行提供给脚本的参数。
file
将迭代 中给出的参数的变量${@}
。
wc -l -- "${file}"
将打印行数的外部命令${file}
(除了when 之外,在这种${file}
情况-
下它将打印其标准输入上的行数)。
答案4
替代使用while
和shift
while [ $# -gt 0 ] ; do
printf '%u lines in %s\n' $(wc -l < "$1") "$1"
shift
done