gpt4 book ai didi

regex - 包含 Perl 一行的 Shell 脚本有空白结果

转载 作者:可可西里 更新时间:2023-11-01 11:50:12 24 4
gpt4 key购买 nike

我有一个在命令行上运行良好的 Perl 单行代码:

perl -nle 'm"\w+:x:\d+:\d+:\S+:/S+:(\S+)$" and $h{$1}++; END{ print "$_: $h{$_}" foreach sort { $h{$b} <=> $h{$a} } keys %h }' /etc/textfile

我已将它放入一个名为 shell.sh 的 shell 文件中,这样下一个人就不必复制/粘贴,只需运行它即可:

#!/bin/sh
perl -nle 'm"\w+:x:\d+:\d+:\S+:/S+:(\S+)$" and $h{$1}++; END{ print "$_: $h{$_}" foreach sort { $h{$b} <=> $h{$a} } keys %h }' /etc/textfile

我尝试在命令行上运行它但没有得到任何结果;它只是加载一个没有输出的新提示。有人看到我做错了什么吗?

以下是一些系统规范:

Linux version 2.6.32-220.13.1.el6.x86_64

(gcc version 4.4.6 20110731 (Red Hat 4.4.6-3) (GCC)

GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)

这是文本文件中的一些内容:

rfink:x:140:140:rat fink:/var/lib/rfink:/sbin/nologin                                 
edible:x:16252:10001:eric idle:/users/eidle/:/bin/bash
tsawyer:x:30855:10001:tom sawyer:/users/tsawyer/:/bin/bash
karthur:x:30886:10001:King Arthur:/users/karthur/:/bin/bash
karthur:x:30886:10001:king arthur:/users/karthur/:/bin/bash
jcash:x:30887:10001:john cash:/users/jcash/:/bin/bash
hpotter:x:30887:10001:harry potter:/users/hpotter/:/bin/bash
triddle:x:30956:10001:tom riddle:/users/triddle/:/bin/bash

最佳答案

快速回答

perl -nle 'm"\w+:x:\d+:\d+:[^:]+:\S+:(\S+)\s*$" and $h{$1}++;
END{ print "$_: $h{$_}" foreach sort { $h{$b} <=> $h{$a} } keys %h }' \
/etc/textfile

您的正则表达式存在三个问题。

  1. 组 ID 之后的字段可以包含空格,因此请将该子模式替换为 [^:]+ 以匹配一个或多个非冒号字符。
  2. 您在子模式中使用了错误的斜杠来匹配主目录。
  3. $ 之前插入 \s* 以允许在每行中使用可选的尾随空格。

输出:

/bin/bash: 7/sbin/nologin: 1

Other approaches

Perl has an awk mode, which would allow

perl -F: -lane '++$sh{$F[-1]};
END{print "$_: $sh{$_}" for sort { $sh{$b} <=> $sh{$a} } keys %sh}' \
/etc/textfile

必须删除尾随空格似乎抵消了句法优势。

perl -F: -lane '($sh = pop @F) =~ s/\s+$//; ++$sh{$sh};
END{print "$_: $sh{$_}" for sort { $sh{$b} <=> $sh{$a} } keys %sh}' \
/etc/textfile

您可以使用管道来获得世界上最好的:

perl -pe 's/[^\S\n]+$//' /etc/textfile |
perl -F: -lane 'print $F[-1]' |
sort | uniq -c | sort -nr

输出转置了列,但您得到的信息相同。

注意 regex double-negative technique 的使用在管道的第一个命令中删除除换行符之外的所有空格。

      7 /bin/bash      1 /sbin/nologin

As a shell script

Your question asks for a shell script, so—to vibe off daxim’s answer—that is

#! /bin/sh

perl -MUser::pwent -le \
'$_->shell && print $_->shell while $_ = getpwent' |
sort | uniq -c | sort -nr

请注意,这不会处理名为 0 的 shell 的病态情况。

如果你不一定要读取系统/etc/passwd,那么你的脚本就变成了

#! /bin/sh

if [ $# -eq 0 ]; then
echo Usage: $0 passwd-file .. 1>&2
exit 1
fi

perl -pe 's/[^\S\n]+$//' "$@" |
perl -lne 'm|\w+:x:\d+:\d+:[^:]+:\S+:(\S+)$| && print $1' |
sort | uniq -c | sort -nr

不同的系统使用不同的格式,所以我建议像上面那样确定你的期望,而不是盲目地打印最后一个字段,不管它是什么。这可能意味着应对偶尔的空输出。

关于regex - 包含 Perl 一行的 Shell 脚本有空白结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10687892/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com