如何替换10000行中的文本

时间:2019-02-05 05:31:32

标签: bash awk sed

我有超过10000个此类文件,我正在尝试将其作为模板

我的琴弦就是这样

"MLKT_3C_AAAU_01A" 
"MLKT_3C_AALI_01A"
"MLKT_3C_AALJ_01A" 
"MLKT_3C_AALK_01A"
"MLKT_4H_AAAK_01A"

我正在尝试将它们转换为此

names(MLKT_3C_AAAU_01A)[2] <- '3C_AAAU_01A' df<- full_join(df,MLKT_CS_4942_01A, by = 'V1')
names(MLKT_3C_AALI_01A)[2] <- '3C_AALI_01A' df<- full_join(df,MLKT_3C_AALI_01A, by = 'V1')
names(MLKT_3C_AALJ_01A)[2] <- '3C_AALJ_01A' df<- full_join(df,MLKT_3C_AALJ_01A, by = 'V1')
names(MLKT_3C_AALK_01A)[2] <- '3C_AALK_01A' df<- full_join(df,MLKT_3C_AALK_01A, by = 'V1')
names(MLKT_4H_AAAK_01A)[2] <- '4H_AAAK_01A' df<- full_join(df,MLKT_4H_AAAK_01A, by = 'V1')

到目前为止,我遇到的最好的方法是使用文本编辑器并使它们一个接一个。我想知道bash中是否可以获取上述字符串并将其转换为我提供的示例?

开始之前,我会删除每一行的引号

sed 's/\"//g' example.txt > exampleout.txt

首先,我尝试在每一行的开头添加names(。因此,假设我的每行包含所有这些字符串的文件称为exampleout.txt。这给了我三个时间名称(而不是一次

awk '$0="names("$0' exampleout.txt > myout.txt

然后我尝试使用以下

)[2] <- '' df<- full_join(df,, by = 'V1')粘贴到每一行的末尾
sed -e 's/$/)[2] <- '' df<- full_join(df,, by = 'V1') /' myout.txt > myout2.txt

所以它导致了我

names(MLKT_3C_AAAU_01A )[2] <-  df<- full_join(df,, by = V1) 
names(MLKT_3C_AALI_01A)[2] <-  df<- full_join(df,, by = V1) 
names(MLKT_3C_AALJ_01A )[2] <-  df<- full_join(df,, by = V1) 
names(MLKT_3C_AALK_01A)[2] <-  df<- full_join(df,, by = V1) 
names(MLKT_4H_AAAK_01A)[2] <-  df<- full_join(df,, by = V1) 

4 个答案:

答案 0 :(得分:3)

您实际上可以在一个命令中完成所有操作。下面的脚本类似于sed,只是我选择使用perl来利用非贪婪匹配(.*?_(.*))来分隔第一个下划线字段。

perl -pe "s/^\"(.*?_(.*))\"$/names(\1)[2] <- '\2' df <- full_join(df, \1, by 'V1')/" example.txt

在这里,我捕获了两个字符串。

  1. 双引号中的所有内容,
  2. 第一个下划线之后的所有内容。

例如,在"MLKT_3C_AAAU_01A"中,第一次捕获将是MLKT_3C_AAAU_01A,第二次捕获将是3C_AAAU_01A

然后,进行适当的替换。


如果第一个下划线之前的字段是常量(例如MLKT),则可以使用sed,用常量替换非贪婪匹配。

sed -E "s/^\"(MLKT_(.*))\"$/names(\1)[2] <- '\2' df <- full_join(df, \1, by 'V1')/" test.txt

请注意使用-E标志(用于扩展正则表达式/更容易的组捕获)和双引号(用于使用单引号作为替换的一部分)。

答案 1 :(得分:2)

请您尝试以下。

awk -v s1="'" '
match($0,/[a-zA-Z][^"]*/){
  val=substr($0,RSTART,RLENGTH)
  split(val,array,"_")
  print "names(" val"[2] <- " s1 array[2]"_"array[3]"_"array[4] s1 " df<- full_join(df," val", by = " s1 "V1" s1")"
}'  Input_file

输出如下。

names(MLKT_3C_AAAU_01A[2] <- '3C_AAAU_01A' df<- full_join(df,MLKT_3C_AAAU_01A, by = 'V1')
names(MLKT_3C_AALI_01A[2] <- '3C_AALI_01A' df<- full_join(df,MLKT_3C_AALI_01A, by = 'V1')
names(MLKT_3C_AALJ_01A[2] <- '3C_AALJ_01A' df<- full_join(df,MLKT_3C_AALJ_01A, by = 'V1')
names(MLKT_3C_AALK_01A[2] <- '3C_AALK_01A' df<- full_join(df,MLKT_3C_AALK_01A, by = 'V1')
names(MLKT_4H_AAAK_01A[2] <- '4H_AAAK_01A' df<- full_join(df,MLKT_4H_AAAK_01A, by = 'V1')

答案 2 :(得分:2)

使用class ConcreteStringDataStore: StringDataStore { func save(data: String, with key: String) { // } func retreive(from key: String) -> String? { return nil } } let test = Test<ConcreteStringDataStore>() 可以轻松地将正则表达式匹配替换为某些内容。

sed

替换文本中的表达式sed 's/^"\(MLKT_\([^"]*\)\)"$/things with \1 and even \2 in it/' file >newfile 对应于正则表达式中的第一个带括号的组,而\1则对应于第二个。因此,如果您匹配\2,则MLKT_1234将是整个字符串,而\1将是\2

如果替换中需要单引号,则必须以某种方式解开它们。也许最简单的机械替换是将每个文字单引号表示为1234,这是您所在的单引号字符串的结尾单引号,然后是文字未引号但反斜杠的单引号,然后是开头的单引号继续在后面的文本中单引号。

不过,对于任何不重要的替代品,也许您想研究一下Awk,它更容易被人理解。

'\''

如果awk '{ # replace double quotes with nothing sub(/^"/, ""); sub(/"$/, ""); # Now you can use $0 to refer to the remaining string # You can replace single quotes with \047 print "names(" $0 ")[2] <- \047" \ substr($0, 6) "\047 df<- full_join(df," \ randomstring ", by = \047V1\047)" }' file >newfile 来自第二个文件,则存在一个通用的Awk模式,可将两个文件(Google用于randomstring的值联接在一起。

答案 3 :(得分:0)

$ awk -F'"' '{
    x=$2; sub(/^[^_]+_/,"",x)
    printf "names(%s)[2] <- \047%s\047 df<- full_join(df,%s, by = \047V1\047)\n", $2, x, $2
}' file
names(MLKT_3C_AAAU_01A)[2] <- '3C_AAAU_01A' df<- full_join(df,MLKT_3C_AAAU_01A, by = 'V1')
names(MLKT_3C_AALI_01A)[2] <- '3C_AALI_01A' df<- full_join(df,MLKT_3C_AALI_01A, by = 'V1')
names(MLKT_3C_AALJ_01A)[2] <- '3C_AALJ_01A' df<- full_join(df,MLKT_3C_AALJ_01A, by = 'V1')
names(MLKT_3C_AALK_01A)[2] <- '3C_AALK_01A' df<- full_join(df,MLKT_3C_AALK_01A, by = 'V1')
names(MLKT_4H_AAAK_01A)[2] <- '4H_AAAK_01A' df<- full_join(df,MLKT_4H_AAAK_01A, by = 'V1')