【问题标题】:change first line of a file using bash使用 bash 更改文件的第一行
【发布时间】:2015-09-23 07:10:48
【问题描述】:

我需要更改文件中的一行。它总是在文件的第一行。

看起来像:

h\tn0   n1  n2  n3  n4  n5  n6  n7  n8  n9  hilu    cjt 1   1000000

除了 h 之外的所有空白处都有一个制表符。

我需要将该行重新转换为

h  n1   n2  n3  n4  n5  n6  n7  n8  n9  
hilu    cjt 1   1000000

在行的开头,\t 和 n0 需要去,并且在 h 和 n1 之间需要有一个制表符。然后换行需要在 hilu 之前开始,但 n9 之后不应该有额外的选项卡

理想情况下,我只需将我的文件提供给脚本,就不需要编写中间脚本来填充。

在 Perl 或 python 中可能有一个高效的版本吗?我考虑过 R,但文件中有 1000 行,只需要更改第一个留置权...

尝试使用 jahid 的解决方案从 r 运行它

> system(paste("sed -r \'1s/(.*)\t(REGION.*)/\1\n\2/;1s/\\t[^[:space:]]+//\'","arg_t1")) 
sed: -e expression #1, char 20: unterminated `s' command

根据我得到的通讯建议

> system(paste("sed -r \"1s/(.*)\t(REGION.*)/\1\n\2/;1s/\\t[^[:space:]]+//\"","arg_t1")) 
sed: -e expression #1, char 20: unterminated `s' command

【问题讨论】:

  • 为什么要给你的问题加上 Perl 标签?
  • @Borodin 我猜“在 perl 或 python 中可能有一个高效的版本吗?”在问题中解决了吗?
  • @Borodin 大概是因为他或她想在 Perl 中这样做。
  • 是的认为这可能只是这种语言有一个有效的版本......我知道我用其他语言考虑的解决方案需要阅读整个文件,其中是 rubish
  • 那么你尝试了什么?

标签: python bash shell awk


【解决方案1】:

对于您的示例,使用 Python 可能是这样的。但您还需要打开文件并获取变量行内的第一行。

import re

line = 'h\tn0   n1  n2  n3  n4  n5  n6  n7  n8  n9  hilu    cjt 1   1000000'
line = re.sub('n9\s*','n9\n', re.sub('h.+n1', 'h\tn1', line))
print line

【讨论】:

  • 你可能想给 OP 一个关于 perl/bash/awk 方言的线索...
【解决方案2】:

这不是 bash 工作,而是 ed 或 sed 的工作。例如,sed -i -e '1s/\\tn0\s*/\t/' -e '1s/\s*\(hilu\)/\n\1/' filename 可以做到这一点。由于 Perl 的基础是 shell、awk 和 sed 的合并,所以也可以类似地使用。

编辑本身效率不高,因为 POSIX 文件语义不允许插入或删除数据,只能(覆盖)写入或截断。因此,此命令复制文件,仅更改开头。如果作为管道的一部分完成(只需删除 -i 以输出到标准输出),它实际上是零成本。此外,数千行数据按照今天的标准仍然很小。

【讨论】:

  • 请注意,就地编辑文件是导致文件系统损坏的方法。 总是通过写入单独的文件然后自动重命名文件来实现文件的读-修改-写(sed 使用临时文件来实现-i),除非您正在实现数据库(请不要)。
【解决方案3】:

使用sed(带有扩展正则表达式):

sed -r '1s/(.*)\t(hilu.*)/\1\n\2/;1s/\\t[^[:space:]]+//' file

就地更改文件:

sed -r --in-place '1s/(.*)\t(hilu.*)/\1\n\2/;1s/\\t[^[:space:]]+//' file

【讨论】:

  • 是否有可能让它接受文件列表,然后对所有文件执行此操作并将它们全部命名为输入
  • somehwo 我在第一个单词和下一个条目 (t1) 之间也有两个制表符...你能不能改变一下?
  • @ktoui 对此感到抱歉,我用tab 替换了\tn0。现在已经修好了。
  • 尝试使用 > system(paste("sed -r --in-place \'1s/(.*)\t(REGION.*)/\1 循环并从 r 内执行\n\2/;1s/\\t[^[:space:]]+//\'","arg_t1") + ) sed: -e expression #1, char 20: unterminated `s' command >
  • 然后我得到 > system(paste("sed -r \"1s/(.*)\t(REGION.*)/\1\n\2/;1s/\\t[ ^[:space:]]+//\"","arg_t1")) sed: -e expression #1, char 20: unterminated `s' command
猜你喜欢
  • 2014-03-21
  • 1970-01-01
  • 2010-10-07
  • 2018-06-12
  • 2019-03-24
  • 1970-01-01
  • 2012-10-10
  • 2010-09-25
  • 2021-12-24
相关资源
最近更新 更多