遍历文件直到匹配并找到第二个不同的匹配项,直到没有匹配项。重复直到 EOF
Iterate through a file until match and find a second, different match, until no match. Repeat until EOF
嗨,我有一个相当大但混乱的盐脚本输出,我是 运行。
基本上我最干净的输出是这样的:
MINION:server1.xyz.com
MINION:server2.xyz.com
MINION:server3.xyz.com
filer1:/vol/storagestuffs/volpath1
filer1:/vol/storagestuffs/volpath2
filer1:/vol/storagestuffs/volpath3
filer1:/vol/storagestuffs/volpath4
MINION:server4.xyz.com
filer4:/vol/storagestuffs/volpath1
MINION:server5.xyz.com
MINION:server6.xyz.com
MINION:server7.xyz.com
filer3:/vol/storagestuffs/volpath1
我想要的只是 return 在其下方具有文件管理器的 minions 以及在其下方的所有文件管理器,我希望将其格式化为:
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath1
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath2
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath3
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath4
MINION:server4.xyz.com filer4:/vol/storagestuffs/volpath1
MINION:server7.xyz.com filer3:/vol/storagestuffs/volpath1
我研究了 if 语句、递归语句等。我要么无法理解 bash 递归语句,要么那不是我想要做的。我希望找到一种无需多次扫描文件即可执行此操作的有效方法。
使用 xargs 有技巧吗? grep 中有什么东西可以做到这一点吗?
感谢您的帮助!
你可以使用 awk:
awk '/^MINION:/{m=[=10=]} /^filer/{print m, [=10=]}' file
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath1
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath2
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath3
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath4
MINION:server4.xyz.com filer4:/vol/storagestuffs/volpath1
MINION:server7.xyz.com filer3:/vol/storagestuffs/volpath1
一个Bash唯一的解决方案是:
minions_with_filers ()
{
label=;
while IFS=: read -r a b; do
case $a in
MINION)
label=$a:$b
;;
filer[0-9]*)
printf '%s %s:%s\n' "$label" "$a" "$b"
;;
esac
done
}
尽管如此,@anubhava 的解决方案将 运行 快 ~10 倍。
用法示例:
$ minions_with_filers < foo.txt
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath1
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath2
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath3
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath4
MINION:server4.xyz.com filer4:/vol/storagestuffs/volpath1
MINION:server7.xyz.com filer3:/vol/storagestuffs/volpath1
嗨,我有一个相当大但混乱的盐脚本输出,我是 运行。
基本上我最干净的输出是这样的:
MINION:server1.xyz.com
MINION:server2.xyz.com
MINION:server3.xyz.com
filer1:/vol/storagestuffs/volpath1
filer1:/vol/storagestuffs/volpath2
filer1:/vol/storagestuffs/volpath3
filer1:/vol/storagestuffs/volpath4
MINION:server4.xyz.com
filer4:/vol/storagestuffs/volpath1
MINION:server5.xyz.com
MINION:server6.xyz.com
MINION:server7.xyz.com
filer3:/vol/storagestuffs/volpath1
我想要的只是 return 在其下方具有文件管理器的 minions 以及在其下方的所有文件管理器,我希望将其格式化为:
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath1
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath2
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath3
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath4
MINION:server4.xyz.com filer4:/vol/storagestuffs/volpath1
MINION:server7.xyz.com filer3:/vol/storagestuffs/volpath1
我研究了 if 语句、递归语句等。我要么无法理解 bash 递归语句,要么那不是我想要做的。我希望找到一种无需多次扫描文件即可执行此操作的有效方法。
使用 xargs 有技巧吗? grep 中有什么东西可以做到这一点吗?
感谢您的帮助!
你可以使用 awk:
awk '/^MINION:/{m=[=10=]} /^filer/{print m, [=10=]}' file
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath1
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath2
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath3
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath4
MINION:server4.xyz.com filer4:/vol/storagestuffs/volpath1
MINION:server7.xyz.com filer3:/vol/storagestuffs/volpath1
一个Bash唯一的解决方案是:
minions_with_filers ()
{
label=;
while IFS=: read -r a b; do
case $a in
MINION)
label=$a:$b
;;
filer[0-9]*)
printf '%s %s:%s\n' "$label" "$a" "$b"
;;
esac
done
}
尽管如此,@anubhava 的解决方案将 运行 快 ~10 倍。
用法示例:
$ minions_with_filers < foo.txt
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath1
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath2
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath3
MINION:server3.xyz.com filer1:/vol/storagestuffs/volpath4
MINION:server4.xyz.com filer4:/vol/storagestuffs/volpath1
MINION:server7.xyz.com filer3:/vol/storagestuffs/volpath1