在Bash shell脚本中将字符串转换为小写并截取字符串的部分

4

我有一个 file.txt 文件,每一行都是这样的:

ABLED   EY B AH L D
ABLER   EY B AH L ER

我想要每行的第二部分:EY B AH L DEY B AH L ER,例如以小写形式保留其余部分的大写形式。我该如何做?非常感谢您提前。
6个回答

8
while read first second; do
    second=$(echo "$second" | tr [:upper:] [:lower:])
    printf '%s\t%s\n' "$first" "$second"
done < file.txt

输出:

ABLED   ey b ah l d
ABLER   ey b ah l er

在KornShell、pdksh或Bash中另外两种不调用tr的方法:

在变量上设置“lowercase”标志(仅适用于KornShell和兼容的shell):

typeset -l second
while read first second; do
    printf '%s\t%s\n' "$first" "$second"
done < file.txt

使用Bash的大小写修改参数扩展修饰符(仅适用于Bash!):

while read first second; do
    printf '%s\t%s\n' "$first" "${second,,}"
done < file.txt

@glennjackman 很好。我喜欢你的两个解决方案比我的更好。我之前都不知道这些功能! - John Kugelman
“declare”和“${,,}”扩展修饰符均不是标准的POSIX“sh”功能。在KornShell中,前者的等效物是可用的,但是它是通过内置命令“typeset”完成的。在pdksh和Bash中也可以使用“typeset -l”。因此,请始终使用“typeset”,而不要使用“declare”。大小写修改扩展修饰符是迄今为止仅适用于Bash的独特扩展功能。 - Greg A. Woods
此外,<<< 是 KornShell 和 Bash 的扩展,在 POSIX sh 中不可用。 - Greg A. Woods

1

可以使用sed命令来完成,使用下面这个非常难懂的脚本:

sed -e 'h;s/ .*//;x;s/[^ ]* //;y/AZERTYUIOPQSDFGHJKLMWXCVBN/azertyuiopqsdfghjklmwxcvbn/;H;x;s/\n/ /' your_file
解释
脚本的第一部分 (h;s/ .*//;x;s/[^ ]* //) 将行的第一个空格之前的部分放入保持空间,将第一个空格之后的部分放入模式空间:
  • h:将实际行复制到保持空间。
  • s/ .*//:仅在模式空间中保留第一个空格之前的字符。
  • x:切换保持和模式空间。
  • s/[^ ]* //:仅在模式空间中保留第一个空格之后的字符。
现在,我们已经将行的第一部分放入了保持空间,第二部分放入了模式空间。我们需要将第二部分转换为小写字母,因此我们使用 y/AZERTYUIOPQSDFGHJKLMWXCVBN/azertyuiopqsdfghjklmwxcvbn/(是的,我有一个 AZERTY 键盘)。
然后,只需要将文件的第一部分和第二部分重新组合即可。
  • H:将模式空间追加到保持空间。
  • x:交换模式空间和保持空间。
  • s/\n/ /:用空格替换H命令的\n

希望您不会对sed语法感到厌恶 ;-).


0
请在脚本开头使用 #!/bin/ksh,即使您想在Linux平台上运行它。这个ksh接受我们在HpUx或Solaris中使用的所有类型变量。

你回答问题的方式不太清楚,为什么会这样呢?你有认真阅读吗?请仔细阅读! - Trinimon

0
如果您知道在读取文件时,文件不会发生更改,并且使用bash:
paste -d " " <(cut -d " " -f 1 your_file) <(cut -d " " -f 2- your_file | tr "[:upper:]" "[:lower:]")

0
如果您想要一个使用管道(而不是粘贴解决方案)且比sed解决方案更易于理解的解决方案,那么这是一个使用awk的解决方案:
awk -F "[ ]" '{str=$1;$1="";print str tolower($0)}' your_file

字段分隔符不能简单地使用" ",因为在这种情况下,连续的空格被视为单个分隔符。


-1
一个Python脚本:
import sys
for l in sys.stdin.read().splitlines():
    try:
        head,rest = l.split(' ', 1)
        print head, rest.lower()
    except: print l

按照以下方式运行它(假设您将脚本保存在名为filter.py的文件中):

$ python filter.py < file.txt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接