【问题标题】:How to seperate words with quotes如何用引号分隔单词
【发布时间】:2021-02-09 07:06:08
【问题描述】:

我正在研究汽车数据集;汽车品牌和型号显示在如下字符串中。你可以假设模型只有一个词。

"Honda civic LX" 
"audi 500s (diesel)"
"toyota camry" 
"ford ranger" 

我想要的输出是在单引号中包含 make(由单个单词组成),而模型和 trim 是在它们自己的单引号中,如下所示:

'honda' 'civic LX'
'audi' '500s (diesel)'
'toyota' 'camry' 
'ford' 'ranger' 

我还应该注意我使用的数据集是这样组织的。

28.0   4   119   82.0   2720   99   1        "audi 500s (diesel)"
23.5   4   225   76.0   5530   81   1        "toyota camry"

我想用 SED 解决它,我已经接近通过以下命令解决它。

sed "s/\"/'/g;s/ /' '/" 

但是,这使我的数据集如下所示。你可以看到它在第一列的末尾添加了一个'',这不是我想要的。另外,我认为该命令会分开品牌和型号,但事实并非如此。

28.0' '  4   119   82.0   2720   99   1        'audi 500s (diesel)'
23.5' '  4   225   76.0   5530   81   1        'toyota camry'

【问题讨论】:

  • sed -E 's/"([^" ]+) +([^"]+)"$/'"'\1' '\2'/"
  • awk -F\" -v q=\' '{sub(/ /,q" "q,$2);$2=q$2q}1'
  • @jhnc 谢谢!您介意分解 SED 命令吗?
  • 除了对单引号/双引号进行稍微神秘的转义外,它只是一个简单的s/// 命令。见:regex101.com/r/pMjctB/1
  • @jhnc 非常感谢。您提供的链接真的很有帮助,我以后一定会使用它!

标签: awk sed command-line


【解决方案1】:

希望这行得通。

sed "s/\"/'/g"| sed -E "s/([a-z])( )/\1' '/"

说明

第一部分(或“查找”部分)([a-z])( ) 查找出现的小写字母后跟空格,分为 2 组,用 () 表示。所以,第一组是字母([a-z]),第二组是空格( )

在第二部分(或替换部分)\1' '\1 表示找到的第一个组(这是反向引用,要使其工作,-E 标志是必不可少的)。如果我们不这样做,字母表和空格都将被' ' 替换,因此我们将丢失最后一个字母表,这将导致类似aud' '500s (diesel)' 的内容。为了保留最后一个字母,我必须这样做。

【讨论】:

  • 谢谢你,这帮助很大。你介意分解第二个表达式吗? "sed -E "s/([a-z])( )/\1' '/" "
【解决方案2】:

我会在这个上使用awk(这使我们在功能及其使用方面更容易),以防你对它没问题。您能否尝试在 GNU awk 中使用所示示例进行跟踪、编写和测试。

awk -v s1="\047" '
match($0,/"[^"]*"/){
  if(RSTART>1){
     printf("%s ",substr($0,1,RSTART-1))
  }
  matched=substr($0,RSTART,RLENGTH)
  num=split(matched,arr," ")
  for(i=1;i<=num;i++){
    gsub(/"/,"",arr[i])
    val=(val?val OFS:"") (s1 arr[i] s1)
  }
  printf("%s%s\n",val,(RSTART+RLENGTH)<length($0)?substr($0,RSTART+RLENGTH+1):"")
  val=""
}
' Input_file

说明:为上述添加详细说明。

awk -v s1="\047" '                            ##Starting awk program from here and creating variable s1 which has single quote in it as a value.
match($0,/"[^"]*"/){                          ##Using match function to match from " to till " here.
  if(RSTART>1){                               ##If RSTART is greater than 1 then do following.
     printf("%s ",substr($0,1,RSTART-1))      ##Printing string sub string of current line from 1 to RSTART-1 here.
  }
  matched=substr($0,RSTART,RLENGTH)           ##Creating matched variable which has regex matched value here.
  num=split(matched,arr," ")                  ##Splitting matched into arr with delimiter of space.
  for(i=1;i<=num;i++){                        ##Running a loop from i=1 to till num value which has number of elements in arr value in it(taken above).
    gsub(/"/,"",arr[i])                       ##Globally substituting " with NULL in arr value here.
    val=(val?val OFS:"") (s1 arr[i] s1)       ##Creating val which has current value of arr wrapped in s1 and keep appending its value to it.
  }
  printf("%s%s\n",val,((RSTART+RLENGTH)<length($0)?substr($0,RSTART+RLENGTH+1):"")) ##Printing val and rest of line here.
  val=""                                      ##Nullifying val here.
}
' Input_file                                  ##Mentioning Input_file name here.

【讨论】:

    猜你喜欢
    • 2017-09-19
    • 1970-01-01
    • 1970-01-01
    • 2020-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多