【问题标题】:Print first letter of each word in a line打印一行中每个单词的首字母
【发布时间】:2015-04-17 18:15:15
【问题描述】:

我搜索了其他帖子,但没有找到适合我需要的答案。我有一个以空格分隔的文件。我想打印给定行中每个单词的第一个字母。例如:

cat test.txt
This is a test sentence.

使用 sed、awk 或组合,我希望输出为“Tiats”。有什么建议可以为我指明正确的方向吗?

【问题讨论】:

  • 在 Haskell 中:main = putStr =<< (unlines . map (map head . words) . lines <$> getContents)
  • 提醒我不要尝试学习 Haskell。我虽然 Perl 很糟糕 :-)
  • @paxdiablo,它只是看起来很糟糕,因为我写它是为了适应一行。我永远不会真的写成那样。

标签: bash awk sed


【解决方案1】:

一种可能性:

pax> echo 'This is a test sentence.
  This is another.' | sed -e 's/$/ /' -e 's/\([^ ]\)[^ ]* /\1/g' -e 's/^ *//'
Tiats
Tia

第一个sed 命令只是确保每行末尾有一个空格以简化第二个命令。

第二个命令将删除每个单词的所有后续字母和尾随空格。这种意义上的单词被定义为任何一组非空格字符。

第三个是添加的,以确保删除每行的前导空格。

【讨论】:

    【解决方案2】:

    在 awk 中:

    awk '{
      for (i=1; i<=NF; i++) {
        printf(substr($i, 1, 1));
      }
      printf("\n");
    }' input_file
    

    awk 自动将 NF 设置为行中的字段数,遍历每个字段并使用 substr 获取第一个字母

    【讨论】:

      【解决方案3】:

      sed 的另一种解决方案:

      sed 's/\(.\)[^ ]* */\1/g' File
      

      在这里,我们查找any character(.),然后是sequence of non-space characters([^ ]*),然后是optional space(*)。将此模式替换为first 字符(与. 匹配的字符)。

      示例:

      $ cat File
      This is a test sentence.
      Ahggsh Mathsh Dansdjksj
      $ sed 's/\(.\)[^ ]* */\1/g' File
      Tiats
      AMD
      

      【讨论】:

      • 最简单的解决方案和可调整的。我需要解析一个用'-'填充的单词,所以我使用了sed -e 's/\(.\)[^-]*-*/\1/g'echo This-is-my-string | sed -e 's/\(.\)[^-]*-*/\1/g' Tims
      【解决方案4】:

      使用 perl:

      $ echo This is a test sentence | perl -nE 'print for /^\w|(?<=\W)./g'
      Tiats
      

      解释:打印任何非空白字符,它是行的开头,或者前面有一个空白。

      【讨论】:

        【解决方案5】:

        另一个 perl 命令。

        $ echo 'This is a test sentence.' | perl -nE 'print for m/(?<!\S)\S/g;print "\n"'
        Tiats
        

        【讨论】:

          【解决方案6】:

          另一个awk

          awk '{for (i=1;i<=NF;i++) $i=substr($i,1,1)}1' OFS= file
          

          这会遍历每个单词并切断除第一个字母之外的所有内容。

          埃克斯:

          cat file
          This is a test sentence.
          Ahggsh Mathsh Dansdjksj
          

          awk '{for (i=1;i<=NF;i++) $i=substr($i,1,1)}1' OFS= file
          Tiats
          AMD
          

          【讨论】:

            【解决方案7】:
            sed 's/ *\([^ ]\)[^ ]\{1,\} */\1/g' YourFile
            

            直接取所有空间长度和位置。假设空格是空格字符而不是制表符(但很容易适应)

            只是为了好玩

            sed 's/ *\(\([^ ]\)\)\{1,\} */\2/g' YourFile
            

            取最后一个字母而不是第一个字母

            【讨论】:

              【解决方案8】:

              在 Haskell 中,一行:

              main = putStr =<< (unlines . map (map head . words) . lines <$> getContents)
              

              也许更易读:

              main = do
                line <- getLine  --Read a single line from stdin
                let allWords = words line --Turn the line into a list of words
                let firsts = map head allWords --Get the first letter of each word
                putStrLn firsts --Print them out
                main --Start over
              

              【讨论】:

                【解决方案9】:

                一个有趣的纯 Bash 解决方案:

                while read -r line; do
                    read -r -d '' -a ary <<< "$line"
                    printf '%c' "${ary[@]}" $'\n'
                done < text.txt
                

                【讨论】:

                  【解决方案10】:

                  这可能对你有用(GNU sed):

                  sed 's/\B.\|[[:space:][:punct:]]//g' file
                  

                  删除单词开头之后的所有字符、空格和标点符号。

                  【讨论】:

                    【解决方案11】:

                    啊,在我找到这个帖子之前,这是一项非常艰巨的任务。 ...我想提取一串单词中的第一个字母。这有效:

                    echo 'Apple banana Carrot fruit-cake (Grapes)' | sed -r 's/.*/\L&/; s/-/ /g; s/[()]//g; s/(.)[^ ]* */\1/g'
                    abcfcg
                    

                    sed -r 's/.*/\L&/; s/-/ /g; s/[()]//g; s/(.)[^ ]* */\1/g'
                    
                    • \L&amp; 将字符串小写(转为大写,使用:\U&amp;
                    • 用空格替换-
                    • 去掉括号()
                    • 此处其他答案的最后一个表达式,特别是@arjun-mathew-dan
                      • 查找任意字符:(.)
                      • 后跟一系列非空格字符:[^ ]*
                      • 后跟可选空格: *
                      • 用第一个字符替换这个模式[匹配(.)]:\1

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2020-08-30
                      • 1970-01-01
                      • 2017-08-02
                      • 2013-12-15
                      • 1970-01-01
                      相关资源
                      最近更新 更多