是否可以在管道中设置变量?
Is it possible to set variable in pipeline?
我有一个很大的 txt 文件,我想在管道中进行编辑。但是在管道的同一个地方,我想在变量 $nol 中设置行数。我只想看看 sintax 如何在管道中设置变量,如:
cat ${!#} | tr ' ' '\n'| grep . ; $nol=wc -l | sort | uniq -c ...
在第二个管道之后是非常错误的,但是在 bash 中我该怎么做呢?
其中一个解决方案是:
nol=$(cat ${!#} | tr ' ' '\n'| grep . | wc -l)
pipeline all from the start again
但我不想对同一件事执行两次脚本,因为我这里的管道更多。
我不能使用 awk 或 sed...
您可以在管道的特定 link 中设置变量,但这不是很有用,因为只有那个特定的 link 会受到它的影响。
我建议只使用一个临时文件。
set -e
trap 'rm -f "$tmpf"' EXIT
tmpf=`mktemp`
cat ${!#} | tr ' ' '\n'| grep . | sort > "$tmpf"
nol="$(wc "$tmpf")"
< "$tmpf" uniq -c ...
您可以使用 tee 和命名管道避免使用临时文件,但它的性能可能不会好多少(甚至可能性能更差)。
在我看来,您好像在问如何避免两次单步执行文件,只是为了同时计算字数和行数。
Bash让你读取变量,wc
可以一次产生你需要的所有数字。
NAME
wc -- word, line, character, and byte count
那么开始...
read words line chars < <( wc < ${!#} )
这会根据从 process substitution 生成的输入填充三个变量。
但是您的问题包括另一个部分命令行,我认为您打算将其作为:
nol=$( sort -u ${!#} | wc -l )
这与您的第一个命令行的字数统计明显不同,因此您不能使用单个 wc
实例来生成两者。相反,一种选择可能是将您的功能放入同时执行这两个功能的脚本中:
read words uniques < <(
awk '
{
words += NF
for (i=1; i<=NF; i++) { unique[$i] }
}
END {
print words,length(unique)
}
' ${!#}
)
您可以使用 tee
然后将其写入您稍后使用的文件:
tempfile="xyz"
tr ' ' '\n' < "${!#}" | grep '.' | tee > "$tempfile" | sort | uniq -c ...
nol=$(wc -l "$tempfile")
或者您可以反过来使用它:
nol=$(tr ' ' '\n' < "${!#}" | grep '.' \
| tee >(sort | uniq -c ... > /dev/tty) | wc -l
更新:
花了一分钟,但我明白了...
cat ${!#} | tr ' ' '\n'| tee >(nol=$(wc -l)) | sort | uniq -c ...
上一个:
我能想到的唯一方法是存储在变量中并回调。您不会多次执行该命令。您只需将输出存储在变量中。
aCommand=($(cat ${!#} | tr ' ' '\n'));sLineCount=$(echo ${#aCommand[@]});echo ${aCommand[@]} | sort | uniq -c ...
- aCommand 将第一组命令的结果存储在一个数组中
- sLineCount 将计算数组中的元素(行)
- ;...回显数组元素并从那里继续执行命令。
我有一个很大的 txt 文件,我想在管道中进行编辑。但是在管道的同一个地方,我想在变量 $nol 中设置行数。我只想看看 sintax 如何在管道中设置变量,如:
cat ${!#} | tr ' ' '\n'| grep . ; $nol=wc -l | sort | uniq -c ...
在第二个管道之后是非常错误的,但是在 bash 中我该怎么做呢?
其中一个解决方案是:
nol=$(cat ${!#} | tr ' ' '\n'| grep . | wc -l)
pipeline all from the start again
但我不想对同一件事执行两次脚本,因为我这里的管道更多。
我不能使用 awk 或 sed...
您可以在管道的特定 link 中设置变量,但这不是很有用,因为只有那个特定的 link 会受到它的影响。
我建议只使用一个临时文件。
set -e
trap 'rm -f "$tmpf"' EXIT
tmpf=`mktemp`
cat ${!#} | tr ' ' '\n'| grep . | sort > "$tmpf"
nol="$(wc "$tmpf")"
< "$tmpf" uniq -c ...
您可以使用 tee 和命名管道避免使用临时文件,但它的性能可能不会好多少(甚至可能性能更差)。
在我看来,您好像在问如何避免两次单步执行文件,只是为了同时计算字数和行数。
Bash让你读取变量,wc
可以一次产生你需要的所有数字。
NAME
wc -- word, line, character, and byte count
那么开始...
read words line chars < <( wc < ${!#} )
这会根据从 process substitution 生成的输入填充三个变量。
但是您的问题包括另一个部分命令行,我认为您打算将其作为:
nol=$( sort -u ${!#} | wc -l )
这与您的第一个命令行的字数统计明显不同,因此您不能使用单个 wc
实例来生成两者。相反,一种选择可能是将您的功能放入同时执行这两个功能的脚本中:
read words uniques < <(
awk '
{
words += NF
for (i=1; i<=NF; i++) { unique[$i] }
}
END {
print words,length(unique)
}
' ${!#}
)
您可以使用 tee
然后将其写入您稍后使用的文件:
tempfile="xyz"
tr ' ' '\n' < "${!#}" | grep '.' | tee > "$tempfile" | sort | uniq -c ...
nol=$(wc -l "$tempfile")
或者您可以反过来使用它:
nol=$(tr ' ' '\n' < "${!#}" | grep '.' \
| tee >(sort | uniq -c ... > /dev/tty) | wc -l
更新:
花了一分钟,但我明白了...
cat ${!#} | tr ' ' '\n'| tee >(nol=$(wc -l)) | sort | uniq -c ...
上一个:
我能想到的唯一方法是存储在变量中并回调。您不会多次执行该命令。您只需将输出存储在变量中。
aCommand=($(cat ${!#} | tr ' ' '\n'));sLineCount=$(echo ${#aCommand[@]});echo ${aCommand[@]} | sort | uniq -c ...
- aCommand 将第一组命令的结果存储在一个数组中
- sLineCount 将计算数组中的元素(行)
- ;...回显数组元素并从那里继续执行命令。