我正在开发一个shell脚本来提供磁盘使用细节。以下是详细信息
#First getting a detail in a variable
duas=$(df -Ph|awk '{printf "%-60s %-40s\n",$1,$5}'|sed 1d|tr "%" " ")
#reading the variable in while loop
while IFS= read -r c1 c2
do
echo First Col: $c1 Second Col: $c2
done < "$duas"
我没有在单独的字段中获取值。你能建议吗。
答案 0 :(得分:0)
问题在于您的输入重定向< "$duas"
。 duas
是一个字符串,而不是文件。您可以使用进程替换在Bash中重写代码,这样:
#!/usr/bin/env bash
while IFS= read -r c1 c2
do
echo "First Col: $c1 Second Col: $c2"
done < <(df -Ph | awk '{printf "%-60s %-40s\n",$1,$5}' | sed 1d | tr "%" " ")
答案 1 :(得分:0)
正如@codeforester已经提到的,您的问题是您尝试使用旨在与文件一起使用的输入重定向表示法从变量中获取输入。
鉴于您的shell脚本和问题标签的外观,我在普通的旧POSIX shell中建议以下内容:
#!/bin/sh
df -Ph |
awk '{printf "%-60s %-40s\n",$1,$5}' |
sed 1d |
tr "%" " " |
while IFS= read -r c1 c2; do
printf 'First col: %s Secnd col: %s\n' "$c1" "$c2"
done
你已经知道的管道角色。将它放在行的末尾会告诉shell假设继续(即你不需要转义换行符)。由于你的while循环只是打印输出而不是填充变量,所以直接输入while read
应该没问题。
请注意,您可以缩短解析df
输出的管道,因为sed
和tr
部分都可以嵌入到awk中:
df -Ph |
awk 'NR>1 {gsub("%"," "); printf "%-60s %-40s\n",$1,$5}' |
while IFS= read ...
根据评论更新
即使我使用
,我也没有在单独的列中获取输出while IFS= read -r c1 c2 do echo "First Col: $c1 Second Col: $c2" done < <(df -Ph | awk '{printf "%-60s %-40s\n",$1,$5}' | sed 1d | tr "%" " ")
是的,这是对的。您正在格式化df
的输出,但之后您正在使用read
根据空格拆分字段。注意:
$ df -Ph | awk '{printf "%-60s %s\n",$1,$5}' | sed 1d | tr "%" " " | head -1
/dev/mapper/poutine-root 78
$ df -Ph | awk '{printf "%-60s %s\n",$1,$5}' | sed 1d | tr "%" " " | head -1 \
> | while read c1 c2; do echo "$c1 / $c2"; done
/dev/mapper/poutine-root / 78
$ df -Ph | awk '{printf "%-60s %s\n",$1,$5}' | sed 1d | tr "%" " " | head -1 | while IFS= read c1 c2; do echo "$c1 / $c2"; done
/dev/mapper/poutine-root 78 /
IFS= read
的影响是,您不能在$c1
和$c2
之间分配输入。遗漏IFS=
的影响是您丢失了输入数据的格式。
如果您希望格式化输出,我建议您控制OUTPUT上的格式,而不是输入。例如:
$ df -Ph | sed 1d | \
> while read c1 _ _ _ c2 _; do printf '%-60s %d\n' "$c1" "${c2%\%}"; done
/dev/mapper/poutine-root 78