【问题标题】:Displaying output without lowercase letters显示不带小写字母的输出
【发布时间】:2013-09-07 22:54:54
【问题描述】:

我有一个格式为:

en Zyung 1 630
en zz%20top%20la%20grange%201st%20guitar%20solo 1 657
en Zz%20top%20la%20grange%20remastered 1 652
en.b %7Eobsidian 1 6937
en.b %C3%9Eie_Nummern/3 2 7521

我希望第一个空格之后的第二个字符串表示“zyung”不应该将小写字母作为第一个字母。我有:

grep -i [a-z] filename

但这将作用于错误行的第一个字符。有什么建议吗?

【问题讨论】:

  • 您应该使您的规范更清晰。每行是否都以en 开头?您要过滤线条还是转换线条?
  • 不,行可以以 en.d 或任何此类字符串开头,但第一个字符串“en/en.v/en.d”和页面名称“Zyung”之间有一个空格。所以空间可以是最好的分隔符。我认为“不应该有小写字母”意味着我想过滤小写字母作为字符串的第一个字母。
  • 我想在文件中输出。
  • @Kent:我同意。有时,一个输出示例值一千字。似乎他想为那些想要帮助的人更加努力地工作。 35分钟后,我仍然不知道他想要达到什么目的。而且这个问题显然似乎并不难解决。
  • @Birei 我猜他是这样想的:“你的预期输出是什么?” “我希望输出是一个文件。” “好的,你的预期输出是多少?” “哦,你真奇怪,你不明白吗,我说我要输出是一个文件!一个文件!”

标签: linux string unix awk grep


【解决方案1】:

要输出第二个单词不以小写字母开头的行(实际上是以非小写字母开头的字符),请使用

    env LANG=C LC_ALL=C awk '$2 ~ /^[^a-z]/' filename

或者,将该输出重定向到另一个文件

    env LANG=C LC_ALL=C awk '$2 ~ /^[^a-z]/' originalfile > newfile

要将每行第二个单词的第一个字母变为大写,请使用

    env LANG=C LC_ALL=C awk '{ $2 = toupper(substr($2,1,1)) substr($2,2) } 1' filename

或者,重定向到另一个文件,

    env LANG=C LC_ALL=C awk '{ $2 = toupper(substr($2,1,1)) substr($2,2) } 1' originalfile > newfile

不要使用originalfile == newfile,因为这不起作用。在命令启动之前,shell 将首先清除文件(因为它是重定向输出,> newfile)。你最终会得到一个空文件。

env LANG=C LC_ALL=C 添加避免了您使用 GNU awk 和非 POSIX 语言环境的情况; gawk[a-z] 匹配任何字母,而不仅仅是小写字母。如果您想要了解区域设置的行为,请使用非 gawk awk,例如 mawk,或者像 Jotne 建议的那样,使用 ^[^[:lower:]] 而不是 ^[^a-z]

【讨论】:

  • 由于某种原因,这没有过滤我需要的内容。您的第二个解决方案最接近我正在寻找的。无论如何谢谢@Nominal Animal
  • @CtrlV:你注意到了一件好事。我错过了模式开头的^(所以它只匹配字符串的开头)。现已修复。
  • 您应该将/^[^a-z]/ 更改为/^[^[:lower:]]/。它更加健壮。我的 ubuntu 对 a-zA-Z 得到相同的结果,都给出了大写和小写。
  • @Jotne:几乎没有更健壮,因为这种行为特定于 GNU awk (gawk)。 (mawk 等人不支持像[:lower:] 这样的字符类,你看。)但是感谢您的提醒;我添加了一个不同的修复程序,并添加了一些文本,如果其他人遇到类似问题,可能会有所帮助。
【解决方案2】:

试试这个 grep:

grep -E '^\S*\s+[A-Z]' file

用你的例子测试:

kent$ echo "en Zyung 1 630
en zz%20top%20la%20grange%201st%20guitar%20solo 1 657
en Zz%20top%20la%20grange%20remastered 1 652"|grep -E '^\S*\s+[A-Z]'
en Zyung 1 630
en Zz%20top%20la%20grange%20remastered 1 652

可以看到,第二行被过滤掉了。

编辑

试试这条线:

grep -E '^\S*\s+[^a-z]' file

【讨论】:

  • 感谢这部分工作。但是该行也可以以特殊字符开头,因此仅显示 [A-Z] 将不起作用。请参阅我编辑的问题。而是忽略小写字母。
  • 试试这个grep -E '^\S*\s+[^a-z]'
  • @CtrlV 请做一个更好的例子,并粘贴预期的输出。
  • 检查 EDIT @CtrlV
猜你喜欢
  • 2015-07-18
  • 2015-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-27
  • 2014-03-02
  • 2017-04-10
  • 2015-07-28
相关资源
最近更新 更多