合并 2 个命令

合并 2 个命令

我需要编写一个 shell 脚本,将文件中的字符转换为小写,并将非字母字符替换为_

我对上述两个命令都有单独的命令。如何将文件作为参数并完成上述操作,即输出将仅包含小写字符,非字母将被替换为_(下划线)?

答案1

使用sed

sed 's/[^[:alpha:]]/_/g; s/[[:upper:]]/\L&/g' file.txt

这实际上是两个sed用 分隔的命令;

  • s/[^[:alpha:]]/_/g将每个非字母字符转换为_

  • s/[[:upper:]]/\L&/g将所有大写字符转换为小写

例子:

$ cat file.txt 
fooBAr132323
SpamEgg

$ sed 's/[^[:alpha:]]/_/g; s/[[:upper:]]/\L&/g' file.txt
foobar______
spamegg

答案2

Python 对此的处理方法:

python -c 'import sys;print "\n".join(["".join([char.lower() if char.isalpha() else "_" for char in line]) for line in sys.stdin])' < input_file.txt

这里的基本思想是我们将每一行拆分成单独的字符并检查该字符是否是字母,然后重建该行,最后用换行符连接所有行以构建一个新文件

使用 /etc/passwd 进行测试:

$ python -c 'import sys;print "\n".join(["".join([char.lower() if char.isalpha() else "_" for char in line]) for line in sys.stdin])' < /etc/passwd | head 

root_x_____root__root__bin_bash_
daemon_x_____daemon__usr_sbin__usr_sbin_nologin_
bin_x_____bin__bin__usr_sbin_nologin_
sys_x_____sys__dev__usr_sbin_nologin_
sync_x_________sync__bin__bin_sync_
games_x______games__usr_games__usr_sbin_nologin_
man_x______man__var_cache_man__usr_sbin_nologin_
lp_x_____lp__var_spool_lpd__usr_sbin_nologin_
mail_x_____mail__var_mail__usr_sbin_nologin_
news_x_____news__var_spool_news__usr_sbin_nologin_

答案3

另一个答案解决了您的直接问题,但对于“组合两个命令”的一般情况的解决方案仍有待提及。信不信由你,Unix 生态系统在设计时就考虑到了这一点,您的 shell 肯定会为您提供一种实现此目的的方法。

如果您想通过命令“管道”提供文件,您可以使用 bash(大概是您正在使用的 shell)中的 |(管道)字符。

其他一些有用的工具也值得在此提及:“cat”实用程序和“>”重定向运算符。

假设您的文件名为 input.txt,并且您想通过管道运行它并将结果称为 output.txt。

让我们逐步构建我们的命令:

$ cat input.txt

这就是我所说的“cat”。无论出于何种目的,它都只会生成文件的内容。现在,让我们在管道中添加第一个命令:“删除非字母”部分。我将从 heemayl 的 sed 命令中取出一部分来执行此操作:

$ cat input.txt | sed 's/[^[:alpha:]]/_/g'

学习 sed 和正则表达式是另一回事,所以现在让我们满足于这个命令能完成我们想要做的事情。添加下一部分:

$ cat input.txt | sed 's/[^[:alpha:]]/_/g' | tr 'A-Z' 'a-z'

我采用了与 heemayl 不同的方法,但效果是一样的。最后,让我们将输出放到我们想要的目的地:

$ cat input.txt | sed 's/[^[:alpha:]]/_/g' | tr 'A-Z' 'a-z' > output.txt

好了,我们完成了。您可以使用 | 运算符将任意数量的命令串在一起,然后使用 > 将输出放入文件中。这是命令行环境中非常常见的任务,因此了解正在发生的事情并习惯使用它很有用。;)

相关内容